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

洛谷原题

原文地址:https://www.cnblogs.com/genshy/p/13893714.html