Codeforces Round #647 (Div. 2)

Problem A

https://codeforces.com/contest/1362/problem/A

判断x/y是不是2的k次方, 如果是

k/3 + (k%3)/2 + (k%3%2)即为答案

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

ll log2(ll a) {
	ll count = 0;
	while (1) {
		if (a >>= 1)
			count++;
		else
			break;
	}
	return count;
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	//freopen("input.txt","r",stdin);
	//freopen("output.txt","w",stdout);
	int t;cin>>t;
	ll x,y;
	ll ans,tmp;
	while(t--){
		cin>>x>>y;
		if(x<y)swap(x,y);
		    if(x==y)cout<<"0"<<endl;
			else{
				if(x%y!=0||(x%y==0&&(x/y&(x/y-1))!=0))cout<<"-1"<<endl;
				else{
					tmp = log2(x/y);
					ans = tmp/3 + (tmp%3)/2 + (tmp%3%2);
					cout<<ans<<endl;
				}
			}
	}
	return 0;
}

Problem B

https://codeforces.com/contest/1362/problem/B

一开始以为模拟过不了, 结果直接暴力模拟就好了...

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

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	//freopen("input.txt","r",stdin);
	//freopen("output.txt","w",stdout);
	set<int> S;
	int t;cin>>t;
	while(t--){
		int n,s,tmp=0,max=-1,flag=1;
		cin>>n;
		while(n--)
		{
			cin>>s;
			if(s>max) 	
				max=s;
			S.insert(s);
		}
		for(int i=1;i<=1024;++i){
			flag = 1;
			for(set<int>::iterator it = S.begin(); it!= S.end(); it++)
        	{
				tmp = i^*it;
				if(!S.count(tmp)){
					flag=0;
				}
			}
			if(flag==1){ 
				cout<<i<<endl;
				break;
			}
		}
		if(flag==0)cout<<"-1"<<endl;
		S.clear();
	}
	return 0;
}

Problem C

https://codeforces.com/contest/1362/problem/C

这题我是打表找规律找出来的
首先可以发现像1,10,100,1000,10000这样的数, 假设最高位为第k位

他们的答案应该是\(2^k-1\) , 又由于一个数可以表示成很多个这样的数相加

比如:

110010 = 100000 + 10000 + 10

那么只需要把第k位为1的各项依次取\(2^k-1\)然后累加即可得到最后的结果

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


int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	int t;cin>>t;
	ll sum=0,cnt=1,tmp=0;
	while(t--){
		ll n;cin>>n;
		while(1)
		{
			tmp = n&1;
			n = n>>1;
			if(tmp==1)
				sum+=pow(2,cnt)-1;
			if(n==0)break;
			cnt++;
		}
		cout<<sum<<endl;
		cnt=0;sum=0;
	}
	return 0;
}

另外一种解法:

for example: input = 5(101)

先来看一组数 :

000

001

010

011

100

可以看到, 第一位每次都变, 第二位每2次变一次, 第三位每4次变一次, 即第k位每\(2^{k+1}\)改变一次, 对于一个十进制数n, 只需要累加\(n/2^{k-1}\)(k表示第k位)即可

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

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	int t;cin>>t;
	while(t--){
		ll ans=0,tmp=0,bi=1;
		ll n;cin>>n;tmp=n;
		while(n)
		{
			ans+=tmp/bi;
			bi<<=1;
			n>>=1;
		}
		cout<<ans<<endl;
	}
	return 0;
}
posted @ 2020-06-05 10:52  roccoshi  阅读(301)  评论(0编辑  收藏  举报