Pinely Round 4 (Div. 1 + Div. 2) (A~D)

题目链接:https://codeforces.com/contest/1991

写在前面

昨晚打的这场cf状态特别不好,打了不到半小时就开始发困了,边听歌边打都止不住困意,打的是一言难尽,下次打cf之前先睡个半小时,身体真是吃不消······

A-Maximize the Last Element

思路

签到题,通过观察不难发现:在数列中是奇数次则可以被取到,是偶数次则无法被取到
遍历一遍找奇数次最大值即可

void solve(){
	int n;cin >> n;
	int maxn=0,k=0;
	for(int i=1;i<=n;++i){
		cin >> a[i];
		if(i & 1) maxn=max(maxn,a[i]);
	} 
	cout << maxn << endl;
	return ;
}

B- AND Reconstruction

思路

考点:构造+模拟
由于 b i = a i A N D a i + 1 b_i = a_i AND a_{i+1} bi=aiANDai+1 ,显然我们可以想到OR运算(或运算)
构造 a i = b i O R b i + 1 a_i=b_i OR b_{i+1} ai=biORbi+1,上述构造可以满足 b 2 到 b n − 2 b_2到b_{n-2} b2bn2,这时我们令 a 1 = b 1 , a n = n n − 1 a_1=b_1,a_n=n_{n-1} a1=b1,an=nn1即可
最后检验是否合法就行

编程

void solve(){
	int n;cin >> n;
	for(int i=1;i<n;++i) cin >> b[i];
	a[1]=b[1],a[n]=b[n-1];
	int flag=0;
	for(int i=2;i<n;++i) a[i]=(b[i]|b[i-1]);
	for(int i=1;i<n;++i){
		if((a[i] & a[i+1])!=b[i]){
			flag=1;
			break;
		}
	}
	if(flag) cout << -1 << endl;
	else{
		for(int i=1;i<=n;++i) cout << a[i] << " ";
		cout << endl;
	} 
	return ;
}

C- Absolute Zero

思路1

考点:构造+模拟
赛时思路: 每次都找数列中的最大值,并取 m i d = 最大值 / 2 mid=最大值/2 mid=最大值/2进行操作,每次可保证值域缩小一半,可以保证在40次以内是可行的

编程1

void solve(){
	int n;cin >> n;
	priority_queue<int> q;
	for(int i=1;i<=n;++i){
		int x;cin >> x;
		q.push(x);
	}
	vector<int> ans;
	int flag=0;
	for(int i=1;i<=40;++i){
		if(q.top()==0){
			flag=1;
			break;
		}
		int mid=(q.top()+1) >> 1;
		ans.push_back(mid);
		queue<int> t;
		while(!q.empty()) t.push(abs(q.top()-mid)),q.pop();
		while(!t.empty()) q.push(t.front()),t.pop();
	} 
	if(flag==0){
		cout << -1 << endl;
		return ;
	}
	cout << ans.size() << endl;
	for(auto i : ans) cout << i << " ";
	cout << endl;
	return ;
}

思路2

首先我们知道 2 30 = 1073741824 > 1 e 9 2^{30}=1073741824>1e9 230=1073741824>1e9,那么我们可以用二进制来解决这道题
先考虑无解的情况,当一个数列有奇数有偶数时,它就无法等于0
因此,这个数列必须是纯奇数 or 纯偶数才有解
在有解的情况下,我们从最大值的一半开始操作,即从 2 29 2 28 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 2 0 2^{29} 2^{28}······2^0 229228⋅⋅⋅⋅⋅⋅20从上往下进行操作
这时如果是奇数的数列,在最后减去1时全部会变为0
如果为偶数的数列,在 2 1 2^1 21已经变为0了,在操作一次 2 0 2^0 20会多出一个1,最后需要在末尾添上1的操作

编程2

void solve(){
	int n;cin >> n;
	int flag1=0,flag2=0;
	for(int i=1;i<=n;++i){
		cin >> a[i];
		if(a[i] & 1) flag1=1;
		else flag2=1; 
	}
	if(flag1 && flag2){
		cout << -1 << endl;
		return ;
	}
	vector<int> ans; 
	for(int i=29;i>=0;i--){
		ans.push_back(1 << i);
	}
	if(flag2) ans.push_back(1);
	cout << ans.size() << endl;
	for(auto i : ans) cout << i << " ";
	cout << endl;
	return ;
}

D- Prime XOR Coloring

思路

考点:构造
众所周知有四色定理:即任何一张地图只用四种颜色就能使具有共同边界的国家着上不同的颜色(我是蒟蒻不会)
因此在本题中大于等于6的数可以大胆猜测颜色至多为4种
一个朴素的想法是奇数同种颜色,偶数同种颜色,这样可以让同色的异或结果为偶数,但是质数2推翻了这个想法
因此我们可以考虑按4的同余类染色,这样就可以使得同色的异或结果为4的倍数,必定不是质数

编程

void solve(){
	int n;cin >> n;
	if(n==1){
		cout << 1 << endl;
		cout << 1 << endl;
	}
	else if(n==2){
		cout << 2 << endl;
		cout << 1 << " " << 2 << endl;
	}
	else if(n==3){
		cout << 2 << endl;
		printf("1 2 2\n");
	}
	else if(n==4){
		cout << 3 << endl;
		printf("1 2 2 3\n");
	}
	else if(n==5){
		cout << 3 << endl;
		printf("1 2 2 3 3\n");
	}
	else{
		cout << 4 << endl;
		for(int i=1;i<=n;++i){
			cout << ((i%4==0)? 4 : i%4) << " ";
		}
		cout << endl;
	}
	return ;
}
  • 24
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值