• 10.28 考试总结


    T1 permutation

    Desprition

    小 R 有 (n) 和一个 (1-n) 的排列,想求它的下一个排列(下一个排列的定义是:(1-n) 的所有全排列按字典序排好后,排在 A 后面的那个叫做 A 的下一个排列。字典序中最后一个排列的下一个排列认为是字典序中第一个排列)。

    (nleq 10^5)

    solution

    No next_permutation

    找规律题。

    首先构造一种方案,从后往前找,找到第一个 (a[i] > a[i+1]) 的数,然后把 (a[i]) 这个数设为 (a[i+1]-a[n]) 中第一个比 (a[i]) 大的数。

    剩下的按从小到大顺序输出就行。

    正确性 对拍请。

    Code

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N = 1e5+10;
    int n,last,a[N],tr[N];
    inline int read()
    {
    	int s = 0,w = 1; char ch = getchar();
    	while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
    	while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0'; ch = getchar();}
    	return s * w;
    }
    int lowbit(int x) { return x & -x; }
    void chenge(int x,int val)
    {
    	for(; x <= n; x += lowbit(x)) tr[x] += val;
    }
    int query(int x)
    {
    	int res = 0;
    	for(; x; x -= lowbit(x)) res += tr[x];
    	return res;
    }
    int main()
    {
    	freopen("permutation.in","r",stdin);
    	freopen("permutation.out","w",stdout);
    	n = read();
    	for(int i = 1; i <= n; i++) a[i] = read();
    	for(int i = n; i >= 1; i--)
    	{
    		int tmp = query(a[i]);
    		if(tmp != n-i)
    		{
    			last = i;
    			break;
    		} 
    		chenge(a[i],1);
    	}
    	int tmp = a[last];
    	for(int i = 1; i < last; i++) printf("%d ",a[i]);
    	sort(a+last,a+n+1);
    	int x = a[lower_bound(a+last,a+n+1,tmp+1)-a];
    	printf("%d ",x);
    	for(int i = last; i <= n; i++) 
    	{
    		if(a[i] == x) continue;
    		printf("%d ",a[i]);
    	}
    	printf("
    ");
    	fclose(stdin); fclose(stdout);
    	return 0;
    }
    

    T2 climb

    Desprition

    给你一颗 (n) 个节点的树,然后给出你每个叶子节点的经过顺序。要求以按顺序遍历这些点,并回到根节点。同时满足每条边都要被经过两次。

    若没有符合条件的路线输出 (-1) 否则按顺序输出依次经过的节点的序号。

    (nleq 10^5)

    solution

    暴力碾压正解。

    首先我们的路径可以写成 (1-a[1]-a[2] ...a[n]) 的形式。

    然后我们把 (a_i -a_{i+1}) 的路径拆成上行和下行两部分。

    然后 一直跳父亲找到经过的节点的编号,同时统计一下每条边经过的次数就可以。

    结果考试的时候数组开小了 (100pts-80pts)

    正解不会。

    Code

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<vector>
    using namespace std;
    const int N = 1e5+10;
    int n,m,tot,cnt,num,last,u,v,flag;
    int a[N],dep[N],fa[N],siz[N],son[N],top[N],head[N],tag[N];
    vector<int> path[50000];
    struct node
    {
    	int to,net;
    }e[N<<1];
    inline int read()
    {
    	int s = 0,w = 1; char ch = getchar();
    	while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
    	while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0'; ch = getchar();}
    	return s * w;
    }
    void add(int x,int y)
    {
    	e[++tot].to = y;
    	e[tot].net = head[x];
    	head[x] = tot;
    }
    void get_tree(int x)
    {
    	dep[x] = dep[fa[x]] + 1; siz[x] = 1;
    	for(int i = head[x]; i; i = e[i].net)
    	{
    		int to = e[i].to;
    		if(to == fa[x]) continue;
    		fa[to] = x;
    		get_tree(to);
    		siz[x] += siz[to];
    		if(siz[to] > siz[son[x]]) son[x] = to;
    	}
    }
    void dfs1(int x,int topp)
    {
    	top[x] = topp;
    	if(son[x]) dfs1(son[x],topp);
    	for(int i = head[x]; i; i = e[i].net)
    	{
    		int to = e[i].to;
    		if(to == fa[x] || to == son[x]) continue;
    		dfs1(to,to);
    	}
    }
    int lca(int x,int y)
    {
    	while(top[x] != top[y])
    	{
    		if(dep[top[x]] < dep[top[y]]) swap(x,y);
    		x = fa[top[x]];
    	}
    	return dep[x] <= dep[y] ? x : y;
    }
    void shuchu(int num,int x,int y)
    {
    	while(x != y)
    	{
    		tag[x]++;
    		if(tag[x] > 2) {flag = 1; return; }
    		path[num].push_back(x);
    		x = fa[x];
    	}
    	path[num].push_back(y);
    }
    int main()
    {
    	freopen("climb.in","r",stdin);
    	freopen("climb.out","w",stdout);
    	n = read();
    	for(int i = 1; i <= n-1; i++)
    	{
    		u = read(); v = read();
    		add(u,v); add(v,u);
    	}
    	while(scanf("%d",&u) != EOF)
    	{
    		cnt++;
    		a[cnt] = u;
    	}
    	get_tree(1); dfs1(1,1);
    	last = 1;
    	for(int i = 1; i <= cnt; i++)
    	{
    		int Lca = lca(a[i],last);
    		if(flag == 1) break;
    		shuchu(++num,last,Lca);
    		shuchu(++num,a[i],Lca);
    		last = a[i];
    	}
    	if(flag == 1) printf("-1
    ");
    	else 
    	{
    		printf("%d ",1);
    		for(int i = 1; i <= num; i++)
    		{
    			if(i & 1) for(int j = 1; j < path[i].size(); j++) printf("%d ",path[i][j]);
    			else for(int j = path[i].size()-2; j >= 0; j--) printf("%d ",path[i][j]);
    		}
    		shuchu(++num,a[cnt],1);
    		for(int j = 1; j < path[num].size(); j++) printf("%d ",path[num][j]);
    	}
    	printf("
    ");
    	fclose(stdin); fclose(stdout);
    	return 0;
    }
    

    T3 pie

    洛谷原题

  • 相关阅读:
    面向对象进阶
    初识面向对象
    模块和包
    day 17递归函数
    pip命令无法使用
    Python中的iteritems()和items()
    C# 截取字符串
    Python连接Mysql数据库
    【PYTHON】 Missing parentheses in call to 'print'
    javaScript中with函数用法实例分析
  • 原文地址:https://www.cnblogs.com/genshy/p/13893714.html
Copyright © 2020-2023  润新知