Codeforces Round #671 (Div. 2) Solved: 5 out of 7

Codeforces Round #671(Div.2)

题目ABCDEF
solved---

✔比赛时通过,⚪比赛时尝试了但是未通过


总结:

  • 读题! 大佬们两分钟就把A题做出来了,我过了半小时才发现题目读错了。早上起来补题的时候又发现B题读错了。。。

A. Digit Game

题意: T组数据,每组数据给出一个长度为n的数组,游戏为玩家一和玩家二两人轮流给数组中的数字打上标记。规则为从玩家一开始,两人轮流;玩家一只能标记奇数位上的数字,玩家二只能标记偶数位上的数字。直到数组中只剩一个数字未标记时,游戏结束。剩下的数字是奇数,则输出1,代表玩家一获胜;是偶数则输出2,代表玩家二获胜。假设两个玩家都是聪明的,每一步都是对自己利益最大化的,根据给出的数组判断最后的获胜人选。

题解:

  • 数组中只有一个数字: 游戏开始即结束,这个数是奇数则直接输出1,偶数则输出2。
  • 数组中有奇数个数字: 奇数位上的数字多于偶数位上的数字,主动权掌握在玩家一手上,只要奇数位上出现过奇数,玩家一就能稳赢。
  • 数组中有偶数个数组: 奇数位上的数字多余偶数位,但是应为游戏从玩家一开始,所以玩家一比玩家二要多标记一个数字。主动权掌握在玩家二手上,只要偶数位上出现过偶数,玩家二稳赢饿。
#include<bits/stdc++.h>
using namespace std;
 
int _T, n, m;
char s[1005];
int main(){
	scanf("%d", &_T);
	while(_T--){
		scanf("%d", &n);
		scanf("%s", s);
		int len = strlen(s);
		int cnt = 0, count = 0;
		for(int i = 0; i < len; i++){
			if((s[i] - '0') % 2 == 1 && (i + 1) % 2 == 1) cnt++;
			else if((s[i] - '0') % 2 == 0 && (i + 1) % 2 == 0)	count++;
		}
		if(n == 1){
			if(cnt)	printf("1\n");
			else 	printf("2\n");
		}else if(n % 2 == 1){
			if(cnt)	printf("1\n");
			else printf("2\n");
		}else{
			if(count)	printf("2\n");
			else printf("1\n");
		}
	}
	return 0;
}

B. Stairs

题意: 楼梯的台阶数不限,但是第i列应该是由i ii个方块叠加形成。如果n阶楼梯由单元格组成的n个不相交的正方形覆盖,则称为nice楼梯(看图中花花绿绿的颜色,一共有7个正方形,同时楼梯也是7阶的)。
在这里插入图片描述
题解: 正确理解题意之后,要找到其中的规律也就不难了。其实一个新的nice楼梯,是在上一个n阶的nice楼梯的旁边,放置一个(n+1)*(n+1)的正方形,然后再正方形之上,再放置一个n阶楼梯,就构成了新的(2*n+1)阶的nice楼梯。由此很容易可以得出,第 i 个nice楼梯的方块数为i * (i + 1) / 2.

#include<bits/stdc++.h> 
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
 
using namespace std;
typedef long long ll;
int _T;
ll x;
 
void run(){
	cin >> x;
	int cnt = 0;
	for(ll i = 1; ; ){
		ll tem = (i + 1) * i / 2;
		if(x < tem)	break;
		x -= tem;
		cnt++;
		i = i * 2 + 1;
	}
	cout << cnt << endl;
}
 
int main(){
	IOS;
	cin >> _T;
	while(_T--)	run();
	return 0;
}

C. Killjoy

题意: 有n个分数以及一个病毒分数,每场比赛可以改变这些分数值,要求是改变量之和为零,与病毒分数相同的分值则会感染病毒,此种病毒具有传染性。问最少需要几场比赛可以感染所有的分数。、

题解: 可以先考虑几种特殊情况:

  • 所有分值都等于病毒分数:那一场比赛都不需要,直接输出零就可以了。答案是0.
  • 这些分数的平均值等于病毒分数:题目要求每场比赛的该变量之和为零,如果平局之等于病毒分数,我们就可以只用一场比赛就感染所有的分数。答案是1.
  • 这些分数中,出现过病毒分值: 相当于在固定的病毒源基础上,我们可以通过改变这个与病毒分数相等发分值,实现多个不同分值的病毒源。具体分值不需要我们去计算,但是我们仍然能够想到,在这种情况下,一场比赛就能感染所有分数。答案是1.
  • 这些分数中没有出现过病毒分值:同上,当我们通过一场比赛获得多个不同分值的病毒源之后,我们能够很轻易地再用一场比赛来感染所有的分数。答案是2.

综上可得程序:

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
 
int _T, n, x, val;
void run(){
	cin >> n >> x;
	int cnt = 0, sum = 0;
	for (int i = 0; i < n; ++i) {
	    cin >> val;
	    cnt += (val == x);
	    sum += val;
	}
	if (cnt == n)
	    cout << 0 << '\n';
	else if (cnt > 0)
	    cout << 1 << '\n';
	else if (sum == n * x)
	    cout << 1 << '\n';
	else 
	    cout << 2 << '\n';
}
 
int main(){
	IOS;
	cin >> _T;
	while(_T--)	run();
	return 0;
}

D1. Sage’s Birthday (easy version)D2. Sage’s Birthday (hard version)

题意: 给定一个长度为n的数组,要求将数组排列成凹口最多的情况,并输出凹口数量和排列后的数组。数组中某一位的数字小于相邻的两个数视为凹口。D1中保证所有的数字均不相等,D2中可能会出现相同的数字。

题解: D1和D2的区别就在于会不会出现重复的数字。其实第一想法就是,将数组排好序,然后连头一次穿插起来,但是这样是不难解决D2的。所以办法是,还是先将数组排好序,将数组对半分成两段,然后依次取出每段的最前面的数字,构成新的数组——就是凹口最多的数组,而凹口数量还需要重新数。

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
 
const int N = 1e5 + 10;
int n, a[N];
vector<int> v;

void run(){
	cin >> n;
	for(int i = 1; i <= n; i++)	cin >> a[i];
	sort(a + 1, a + n + 1);
	if(n % 2 == 0)	v.push_back(a[n / 2]);
	for(int i = 1; i <= (n - 1) / 2; i++){
		v.push_back(a[n / 2 + i]);
		v.push_back(a[i]);
	}
	v.push_back(a[n]);
	int cnt = 0;
	for(int i = 1; i < v.size() - 1; i++)
		if(v[i] < v[i - 1] && v[i] < v[i + 1])
			cnt++;
	cout << cnt << endl;
	for(auto i : v)	cout << i << " ";
}
 
int main(){
	IOS;
	run();		
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值