Codeforces Round #628 (Div. 2)

题目入口

A. EhAb AnD gCd (构造)
B. CopyCopyCopyCopyCopy (构造)
C. Ehab and Path-etic MEXs (构造)
D. Ehab the Xorcist (构造)
E.
F.

A. EhAb AnD gCd

题意描述: 给定x,输出任意一组满足条件的 a,b;
在这里插入图片描述
题解: 很明显最简单的一组a b是 1 ,x-1

#include<bits/stdc++.h>
using namespace std;

int main()
{
	int T;
	cin>>T;
	while(T--){
		int n;
		cin>>n;
		cout<<"1 "<<n-1<<endl;
	}
	return 0;
}

B. CopyCopyCopyCopyCopy

题意描述: 长度为n的数组可以复制n次连接起来,组成一个新数组,求最长上升子序列的大小(LIS);
题解: 很明显,不重复的数的个数就是答案;

#include<bits/stdc++.h>

using namespace std;
int main()
{
	int T;
	cin>>T;
	while(T--){
		int n,t;
		cin>>n;
		vector<int> a;
		for(int i=0;i<n;i++) cin>>t, a.push_back(t);
		
		sort(a.begin(),a.end());
		a.erase(unique(a.begin(),a.end()),a.end());
		cout<<a.size()<<endl;
	}
	return 0;
}

C. Ehab and Path-etic MEXs

来自codeforces
题意描述:
从 [0, n-2] 中不重复地选数给每条边赋权值,任意两点之间的简单路径中,在边的权值中没出现过的非负整数中最小的数为xi,选取方案使xi中最大的数最小,输出给每条边赋权值的方案(任意一种);
题解: 有两个方向可以去考虑最优解(代码为1):
1、从0开始给叶子节点上的边赋值,然后再给其他边赋值。这样可以使较小的数较少的出现在其他两点之间。那么最大值就最小了。
2、找到度数为3的点,吧0,1,2给这三条边,那么0,1,2不会出现在同一条路径上,那么最优解就是2,若没有找到,此时为一条链,那么最优解就是 n-1。

#include<bits/stdc++.h>

using namespace std;

pair<int,int> pa[100010];
int in[100010];
int main()
{
	int n;
	cin>>n;
	for(int i=0;i<n-1;i++){
		cin>>pa[i].first>>pa[i].second;
		in[pa[i].first]++ , in[pa[i].second] ++;
	}
	int num=0;
	for(int i=1;i<=n;i++) if(in[i]==1) num++;  
	
	int vis=0;
	for(int i=0;i<n-1;i++){
		if(in[pa[i].first]==1 || in[pa[i].second]==1) cout<<vis<<"\n",vis++;
		else cout<<num<<"\n",num++;
	}
	return 0;
}

D. Ehab the Xorcist

题意描述: 给定 u ,v,寻找一组数使得:这组数的异或和= u ,这组数的和 = v。寻找这组数的大小最小的任意一组,输出这组数的大小及每一个数,找不到就输出 -1;
题解: 很明显如果存在最优解,那么这组数的个数不会超过3:因为,u^0= u,而x ^ x= 0,如果存在 x+x = v - u,那么u ^ x ^ x = u,u+x+x= v,解为 u ,x,x ;但此时要考虑是否有更优解2:那么如果(u+x) ^ x= v,那么解为 v+x,x;其他特殊情况另作讨论即可;

#include<bits/stdc++.h>

using namespace std;

int main()
{	
	long long a,b;
	cin>>a>>b;
	if(a==0){
		if(b==0) cout<<0<<endl;
		else {
			if(b%2==0) {
				cout<<2<<endl;
				cout<<b/2<<" "<<b/2<<endl;
			}
			else {
				cout<<-1<<endl;
			}
		}
	}
	else if(a==b) {
		cout<<1<<endl;
		cout<<a<<endl;
	}
	else if(b>a && (b-a)%2==0){
		long long t = (b-a)/2;
		if(((t+a)^t) == a) {
			cout<<2<<endl;
			cout<<t+a<<" "<<t<<endl; 
		}
		else {
			cout<<3<<endl;
			cout<<a<<" "<<(b-a)/2<<" "<<(b-a)/2<<endl;
		}
	}
	else cout<<"-1\n";
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值