C. Killjoy(思维+贪心) Codeforces Round #671 (Div. 2)

127 篇文章 3 订阅

原题链接: https://codeforces.com/contest/1419/problem/C

在这里插入图片描述
测试样例

input
3
2 69
68 70
6 4
4 4 4 4 4 4
9 38
-21 83 50 -59 -77 15 -71 -78 20
output
1
0
2

Note

In the first test case it’s possible to make all ratings equal to 69. First account’s rating will increase by 1, and second account’s rating will decrease by 1, so the sum of all changes will be equal to zero.

In the second test case all accounts will be instantly infected, because all ratings (including Killjoy’s account’s rating) are equal to 4.

题意: killjoy现在是个感染者,有 n n n个用户他们都有着各自的评分,现在感染规则为:若有用户的评分与感染者的评分相同,则也被感染,并无法恢复。感染时间可发生在比赛中或比赛后。killjoy可以进行codeforces比赛(killjoy不能参加),可以对用户进行任意的分数操控,但所有总和必须为0。问Killjoy最少需要进行多少场比赛才能感染所有人。

解题思路: 由于killjoy不能参加比赛,所以他只能在赛前和赛后感染别人。特殊的一点,在比赛过程中分数是可以不断变化的,过程中你想加多少分就加多少分,但最后总和必须是0。OK,我们知道这些就可以来分析了。

  • 如果n个人的评分都是x,那么不需要进行比赛就可以直接感染了。
  • 如果n个人的评分总和平均值为x,那么我们只要进行一场比赛就可以让所有人的评分都变为x。
  • 如果n个人中存在一个或多个评分为x的人,那么在比赛前killjoy就可以感染他们,这样有什么用呢?那么在一场比赛中,这些人就可以感染其他所有人。(想法是未感染人评分先变为x,感染之后再变为原评分。这样总和是不变的。)
  • 如果都不是,那么我们可以先进行一场比赛使其变成第三种情况,然后自然可以达成效果。所以需要两场。

情况分析完之后,则此题易解。

AC代码

/*
*邮箱:unique_powerhouse@qq.com
*blog:https://me.csdn.net/hzf0701
*注:文章若有任何问题请私信我或评论区留言,谢谢支持。
*
*/
#include<bits/stdc++.h>	//POJ不支持

#define rep(i,a,n) for (int i=a;i<=n;i++)//i为循环变量,a为初始值,n为界限值,递增
#define per(i,a,n) for (int i=a;i>=n;i--)//i为循环变量, a为初始值,n为界限值,递减。
#define pb push_back
#define IOS ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
#define fi first
#define se second
#define mp make_pair

using namespace std;

const int inf = 0x3f3f3f3f;//无穷大
const int maxn = 1e5;//最大值。
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll>  pll;
typedef pair<int, int> pii;
//*******************************分割线,以上为自定义代码模板***************************************//

int t;
int n,x;
int a[maxn];
int main(){
	//freopen("in.txt", "r", stdin);//提交的时候要注释掉
	IOS;
	while(cin>>t){
		while(t--){
			cin>>n>>x;
			ll sum=0;
			bool flag1=false,flag2=false;
			rep(i,1,n){
				cin>>a[i];
				if(a[i]==x){
					flag2=true;
				}
				else{
					flag1=true;
				}
				sum+=a[i];
			}
			if(!flag1){
				//说明都为x,可以不用进行比赛直接感染
				cout<<0<<endl;
			}
			else if(sum==n*x||flag2){
				//说明参与者存在感染者,直接在比赛中就可以感染所有人,或者经过一场比赛后所有人都变为x再感染。
				//所以只需要一场。
				cout<<1<<endl;
			}
			else{
				cout<<2<<endl;
			}
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HeZephyr

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值