Codeforces Round #847 (Div.3) A-E

Codeforces Round #847 (Div.3) A-E

思路讲解点这里

A. Polycarp and the Day of Pi

**题意:**输入一个字符串,从第一个字符开始与pi逐位匹配,若某个字符不同则退出匹配。

void solve(){
	string tmp = "314159265358979323846264338327";
	
	string s;
	cin >>s;
	
	int ans = 0; 
	for(int i=0;i<s.length();i++){
		if(s[i]==tmp[i])	ans++;
		else			break;
	}
	cout <<ans<<endl;
}

B. Taisia and Dice

题意:n1-6点数的骰子,他们的点数总和为s,现有猫猫偷走一个最大点数的骰子之后他们的点数总和为r,求出这n个骰子分别的点数

**思路:**偷之前总和为s,偷之后总和为r, 说明被偷走的骰子点数为s-r且为最大值,然后动态输出剩下骰子点数的平均值即可

代码:

void solve(){
	int n,s,r;
	cin >>n>>s>>r;
	
    cout <<s-r<<" ";
    n--;

    while(n--){
        cout<<r/(n+1)<<" ";
        r-=r/(n+1);
    }
    cout<<endl;
}

C. Premutation

**题意:**现有一个长度为n的排列(未知),然后给定n个关系,用着若干个关系求出原始排列

例如:

​ 现给出4个关系:[2,1,3][4,1,3][4,2,3][4,2,1]

​ 可以这么理解:[2,1,3] 21的前面,13的前面……

​ 得出原始排列为 p = [4,2,1,3]

**思路:**可以看成一份班级排名有不同版本的成绩单,然后分别给第1至n名学生n至1分数(分数越高越靠前)

代码:

struct node{
	int i;
	int v;
}a[105];

bool cmp(node a,node b){
	return a.v>b.v;
}

void solve(){
	int n;
	cin >>n;
	for(int i=1;i<=n;i++){
		a[i].i=i;
		a[i].v=0;
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n-1;j++){
			int num;
			cin >>num;
			a[num].v+=j;
		}
	}
	sort(a+1,a+1+n,cmp);
	for(int i=n;i>=1;i--){
		cout <<a[i].i<<" ";
	}cout <<endl;
}
D. Matryoshkas

**题意:**现有一个长度为n的排列(未知),然后给定n个关系,用着若干个关系求出原始排列

例如:

​ 现给出4个关系:[2,1,3][4,1,3][4,2,3][4,2,1]

​ 可以这么理解:[2,1,3] 21的前面,13的前面……

​ 得出原始排列为 p = [4,2,1,3]

**思路:**可以看成一份班级排名有不同版本的成绩单,然后分别给第1至n名学生n至1分数(分数越高越靠前)

代码:

void solve(){
	int n;
	cin >>n;
	map<int,int> mp;
	map<int,bool> vis;
	for(int i=1;i<=n;i++){
		int num;cin >>num;
		mp[num]++;
		vis[num]=1;
	}
	int ans = 0;
	int num = 0;
	for(auto i:mp){
		if(num==0)	num=i.second;
		if(num>i.second){
			ans+=(num-i.second);
			num=i.second;
		}
		if(num<i.second){
			num=i.second;
		}
		if(vis[i.first+1]==0){
			ans+=num;
			num=0;
			continue;
		}
		if(num!=i.second)	num=i.second;
	}
	cout <<ans+num<<endl;
}
E. Vlad and a Pair of Numbers

**题意:**给定一个x,找出两个数字 ab 使得 x=a⊕b=(a+b)/2

思路:

  1. x 不能是奇数,否则两数异或必定为奇数,再除 2 就变成非整数。则输出-1
  2. x/2 的二进制表示中,若出现1,则 x 的二进制表示中同一位置不能出现 "1"。则输出-1
  3. 然后输出x^(x/2)即可。(代码为暴力过程,暴力思路见视频

代码(能A,但暴力,下面有结论代码):

void solve(){
	int n;
	cin >>n;
	int nn = n/2;
	if(n&1){
		cout <<-1<<endl;
		return;
	}
	string s = "";
	int num = 0;
	while(n){
		if(n&1)	s+="1";
		else	s+="0";
		n/=2;
	}
	int tmp = 1;
	for(int i=0;i<s.length();i++){
		if(s[i]=='1')	num+=tmp;
		tmp*=2;
	}
	string ss = "";
	while(nn){
		if(nn&1)	ss+="1";
		else		ss+="0";
		nn/=2;
	}

	for(int i=0;i<ss.length();i++){
		if(ss[i]=='1'&&s[i]=='1'){
			cout <<-1<<endl;
			return;
		}
	}
	
	int ans_1 = 0,ans_2=0;
	tmp = 1;
	if(s.length()>ss.length())	ss+='0';
	for(int i=0;i<s.length();i++){
		if(s[i]=='0'){
			if(ss[i]=='1'){
				ans_1+=tmp;
				ans_2+=tmp;
			}
		}else{
			if(ss[i]=='0'){
				ans_2+=tmp;
			}
		}
		tmp*=2;
	}
	cout <<ans_1<<" "<<ans_2<<endl;
}

代码:

void solve(){
	int n;
	cin >>n;
	if(n&1){
		cout <<-1<<endl;
		return;
	}
	int a = n;
	int b = n/2;
	string s = "",ss = "";
	
	while(a){
		if(a&1)	s+="1";
		else	s+="0";
		a/=2;
	}
	while(b){
		if(b&1)	ss+="1";
		else	ss+="0";
		b/=2;
	}
	
	for(int i=0;i<ss.length();i++){
		if(ss[i]=='1'&&s[i]=='1'){
			cout <<-1<<endl;
			return;
		}
	}
	int ans = n^(n/2);
	cout <<n/2<<" "<<ans<<endl;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值