Codeforces Global Round 8 A~D

E题不会了,提前写一下博客。(不保证一定正确,

A. C+=

题意:给你两个数a, b,你可以执行操作:a += b 或者 b += a。问最少执行多少次操作之后,a,b中的至少一个数大于给定的n。

思路:每一次操作改变a,b中的小值即可,因为a+b对两者是一样的。

代码:

#include <iostream>
 
using namespace std;
 
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	long long T, a, b, c;
	cin>>T;
	while(T--){
		cin>>a>>b>>c;
		if(a > b) swap(a, b);
		int ans = 0;
		while(b <= c){
			int t = b;
			b = a + b;
			a = t;
			ans += 1;
		}
		cout<<ans<<'\n';
	}
	return 0;
}

B. Codeforces Subsequences

题意:给你一个k,输出一个字符串,该字符串至少包含k个子序列为codeforces,且长度最短。

思路:对于codeforces,我们可以得到1*1*1*1*1*1*1*1*1*1=1(子序列为codeforces的数目),某一位字母在原位置加一后,对应的公式内的值也加一,又因为平摊得到的乘积最大,因此循环直到满足条件输出即可。

代码:

#include <iostream>

using namespace std;

char s[11] = "codeforces";
int num[11];


int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	long long k;
	int pos = 0;
	cin>>k;
	for(int i = 0; i < 10; ++i)
		num[i] = 1;
	while(1){
		long long sum = 1;
		for(int i = 0; i < 10; ++i){
			sum *= num[i];
		}
		if(sum >= k){
			for(int i = 0; i < 10; ++i){
				for(int j = 0; j < num[i]; ++j){
					cout<<s[i];
				}
			}
			cout<<'\n';
			return 0;
		}
		num[pos] += 1;
		pos = (pos+1)%10;
	}
	return 0;
}

C - Even Picture

题意:在一张无限大的网格纸上,每一个网格初始为白色,现在给定一个n,你可以将网格涂成灰色,要求其中灰色网格的四个相邻网格都为灰色的网格个数恰好为n个,同时每个灰色网格的灰色邻居都为偶数个,而且每个灰色网格都能不经过白色网格而到达其它任意灰色网格,输出每个点的坐标。

思路:找到一个合适的可循环的图形即可,我找的是品字形。

代码:

#include <iostream>
#include <set>

using namespace std;

void print(int x, int y){
	if(y == 0)
		cout<<x<<' '<<y<<'\n';
	cout<<x+1<<' '<<y<<'\n';
	cout<<x+2<<' '<<y<<'\n';
	cout<<x<<' '<<y+1<<'\n';
	if(!(y == 0 && x != 0))
		cout<<x<<' '<<y+2<<'\n';
	cout<<x+1<<' '<<y+2<<'\n';
	cout<<x+2<<' '<<y+1<<'\n';
	cout<<x+2<<' '<<y+2<<'\n';
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	int n, ans = 0;
	cin>>n;
	int pos1x = 4, pos2x = 6;
	ans = 15 + 7*(n-1);
	cout<<ans<<'\n';
	print(0, 0);
	print(2, 2);
	for(int i = 1; i < n; ++i){
		if(i%2){
			print(pos1x, 0);
			pos1x += 4;
		}else{
			print(pos2x, 2);
			pos2x += 4;
		}
	}
	return 0;
}

D - AND, OR and square sum

题意:给你一个长度为n的数组,你可以选择两个数a, b,使得a = a & b, b = a | b。你可以进行任意次数这样的操作,问最后数组元素的平方和最大为多少。

思路:这两个操作实际上是将a的二进制下为1而b的二进制下为0的位的值给交换了,因此最后的数组中所有元素的二进制下的每个位置下的1的数目不变,因此,我们先求出每个位置的1的数目,然后贪心使得当前数最大即可。

代码:

#include <iostream>

using namespace std;

int num[70];

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	long long ans = 0;
	int n, t;
	cin>>n;
	while(n--){
		cin>>t;
		int pos = 0;
		while(t){
			num[pos++] += t%2;
			t /= 2;
		}
	}
	while(1){
		long long t = 0;
		for(int i = 69; i >= 0; --i){
			t *= 2;
			if(num[i] > 0){
				t += 1; num[i] -= 1;
			}
		}
		ans += t*t;
		if(t == 0) break;
	}
	cout<<ans<<'\n';
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值