Codeforces Round #499 (Div. 2)

Codeforces Round #499 (Div. 2)


A. Stages

  • 有n个字符,你要取k个,使得这k个字符的最小间距>=2。求这k个字符的和最小是多少。
  • 从a开始贪心即可。

B. Planning The Expedition

  • 有k个人,n个数字,每个都要选x个数字,且保证每个人选的x个数字都相等,求x最多是多少?
  • 二分即可。二分x,check一下。由于此题的x范围较小,暴力即可。

C. Fly

  • 有一艘火箭重k,现在需要游历n个星球,众说周知的是,火箭在降落星球和某个星球起飞需要消耗燃料,你只能从第1个星球装燃料,问,最多需要装多少燃料?
  • 贪心。最优情况肯定是,飞完第n个星球刚刚好把所有的燃料用完,$$frac{x+t}{b[n]}=t$$,x为火箭质量,t为最后一次飞行前的燃料,b[n]为转化率,最后一次飞行会导致燃料用光。然后这个公式反复迭代即可。
  • 虽然我是用二分过的,不过并不感觉能过的样子。

D. Rocket

  • 交互题,没看懂

E. Border

  • 你有很多面值的钞票,每一种面值的有无数张,你可以任意的组合,求所有的组合对k取模,不相同的计数,是多少。
  • 我们对所有的钞票和k取gcd,这样得到的数,可以保证它和它的倍数一定能构造出来,然后输出它在k内的取值即可。

F. Mars rover

  • 有一棵树。树上的所有叶子作为输入,0或者1,非叶子结点有一个操作,or,xor,not,and。保证如果是or,xor,and,则有两个儿子结点,如果是not,则有1个儿子结点。这样之后,所有的结点有一个值,保证1结点为根。问,按顺序改变叶子结点的取值,0改为1,1改为0,根结点的取值是多少。
  • 很水的一道题啊。
  • 先做一遍dfs,获得根的值,顺便获得树上每个点的取值。然后,从根结点开始,再做一遍dfs。dp[i]代表改变这个结点的取值,会不会使根结点的值改变。那么可以推出转移方程:dp[v]=dp[u]*k。(u是v的父亲,若改变v的取值,u的值改变了,k=1,若u的值不变,k=0)。下推到叶子,dp[k]^sum[k],即为答案。

#include"stdio.h"
#include"string.h"
//and 1 or 2 not 3 in 4 xor 5
int a[1050000][5];
int sum[1050000];
int dp[1050000];
int dfs(int k) {
	int x,y;
	if (a[k][0]==4)  {sum[k]=a[k][1];return a[k][1];}
	if (a[k][0]==3) {
		 x=dfs(a[k][1]);
		 sum[k]=x^1;
		return (x^1);
	}
	if (a[k][0]==1) {
		x=dfs(a[k][1]);
		y=dfs(a[k][2]);
		sum[k]=x&y;
		return (x&y);
	}
	if (a[k][0]==2) {
		x=dfs(a[k][1]);
		y=dfs(a[k][2]);
		sum[k]=x|y;
		return (x|y);
	}
	if (a[k][0]==5) {
		x=dfs(a[k][1]);
		y=dfs(a[k][2]);
		sum[k]=x^y;
		return (sum[k]);
	}
}
//and 1 or 2 not 3 in 4  xor 5
void find(int k){
	if (a[k][0]==1) {
		if (sum[a[k][1]]==1&&sum[a[k][2]]==1) {
			dp[a[k][1]]=1*dp[k];
			dp[a[k][2]]=1*dp[k];
		}
		if (sum[a[k][1]]==1&&sum[a[k][2]]==0) {
			dp[a[k][1]]=0*dp[k];
			dp[a[k][2]]=1*dp[k];
		}
		if (sum[a[k][1]]==0&&sum[a[k][2]]==1) {
			dp[a[k][1]]=1*dp[k];
			dp[a[k][2]]=0*dp[k];
		}
		if (sum[a[k][1]]==0&&sum[a[k][2]]==0) {
			dp[a[k][1]]=0*dp[k];
			dp[a[k][2]]=0*dp[k];
		}
		find(a[k][1]);
		find(a[k][2]);
	}
	if(a[k][0]==2) {
		if (sum[a[k][1]]==1&&sum[a[k][2]]==1) {
			dp[a[k][1]]=0*dp[k];
			dp[a[k][2]]=0*dp[k];
		}
		if (sum[a[k][1]]==1&&sum[a[k][2]]==0) {
			dp[a[k][1]]=1*dp[k];
			dp[a[k][2]]=0*dp[k];
		}
		if (sum[a[k][1]]==0&&sum[a[k][2]]==1) {
			dp[a[k][1]]=0*dp[k];
			dp[a[k][2]]=1*dp[k];
		}
		if (sum[a[k][1]]==0&&sum[a[k][2]]==0) {
			dp[a[k][1]]=1*dp[k];
			dp[a[k][2]]=1*dp[k];
		}
		find(a[k][1]);
		find(a[k][2]);
	}
	if (a[k][0]==3) {
		dp[a[k][1]]=1*dp[k];
		find(a[k][1]);
	}
	if (a[k][0]==5) {
		dp[a[k][1]]=1*dp[k];
		dp[a[k][2]]=1*dp[k];
		find(a[k][1]);
		find(a[k][2]);
	}
}
int pp[1050000];
char s[105000];
int main(){
	int n,i,l;
	scanf("%d",&n);
	l=0;
	for (i=1;i<=n;i++){
		scanf("%s",s);
		if (s[0]=='A') {
			a[i][0]=1;
			scanf("%d %d",&a[i][1],&a[i][2]);
		}
		if (s[0]=='O') {
			a[i][0]=2;
			scanf("%d %d",&a[i][1],&a[i][2]);
		}
		if (s[0]=='N') {
			a[i][0]=3;
			scanf("%d",&a[i][1]);
		}
		if (s[0]=='I') {
			a[i][0]=4;
			scanf("%d",&a[i][1]);
			l++;
			pp[l]=i;
			
		}
		if (s[0]=='X') {
			a[i][0]=5;
			scanf("%d %d",&a[i][1],&a[i][2]);
		}
	}
	memset(sum,0,sizeof(sum));
	dfs(1);
	memset(dp,0,sizeof(dp));
	dp[1]=1;
	find(1);
	for (i=1;i<=l;i++) {
		printf("%d",dp[pp[i]]^sum[1]);
	}
	printf("
");
}
原文地址:https://www.cnblogs.com/nowheretrix/p/9382214.html