Codeforces Round #618 (Div. 2)

Codeforces Round #618 (Div. 2)

http://codeforces.com/contest/1300

A - Non-zero

思路:首先0就加到1,然后如果总和为0的话肯定有正数,将其中任意一个加1就好

#include<bits/stdc++.h>
#define MAXN 105
using namespace std;
int t,n,a[MAXN];
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		int ans = 0,sum = 0;
		for(int i = 1;i <= n;++i)
		{
			scanf("%d",&a[i]);
			if(a[i] == 0)
				++ans,a[i] = 1;
			sum += a[i];
		}
		if(sum == 0)
			++ans;
		printf("%d\n",ans);
	}
	return 0;
}

B - Assigning to Classes

思路:首先将原数组排好序,设原数组为
x个数,a1,y个数,a2,z个数
其中 x + 1 + y + 1 + z = 2 ∗ n x + 1 + y + 1 + z = 2 * n x+1+y+1+z=2n
我们要设置一种划分方法使得a1,a2变为两个数组的中位数
设数组1从x中取x1个数,从y中取x2个数,从z中取x3个数,再取上a1,要将a1变为中位数则要满足 x 1 = x 2 + x 3 x1 = x2 +x3 x1=x2+x3
剩下的数即在数组2中,要使得a2为中位数要满足 x − x 1 + y − x 2 = z − x 3 x-x1+y-x2 = z-x3 xx1+yx2=zx3
解得 z + x 2 + 1 = n z+x2+1 = n z+x2+1=n
现固定z,那么a2的值就已知了,然后很明显y越小a2和a1的差越小,但 y > = x 2 y >= x2 y>=x2,所以 y = x 2 y = x2 y=x2,即z + y + 1 = n,所以 a 1 = a [ n ] a1 = a[n] a1=a[n]已经确定了,只要取y = 0,即 a 2 = a [ n + 1 ] a2 = a[n+1] a2=a[n+1]即为最优解

#include<bits/stdc++.h>
#define MAXN 200005
using namespace std;
int n,t,a[MAXN];
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		for(int i = 1;i <= 2* n;++i)
			scanf("%d",&a[i]);
		sort(a+1,a+2*n+1);
		printf("%d\n",a[n+1] - a[n]);
	}
	return 0;
}

C - Anu Has a Function

思路:对于f(x,y),可以发现对于每一位
x 0 0 1 1
y 0 1 0 1
ans 0 0 1 0
即只有1,0这种情况运算结果为1
由此可知对于数组a,对于每一位,如果a[i]这一位为1,数组中其它数这一位都为0,那么我将i放到第一个这一位结果即为1,对于其他情况这一位结果都会是0,所以我直接从高位到低位枚举看是否有让这一位结果变为1的方案即可

#include<bits/stdc++.h>
#define MAXN 100005
using namespace std;
int n,a[MAXN];
int main()
{
	scanf("%d",&n);
	for(int i = 1;i <= n;++i)
		scanf("%d",&a[i]);
	int ans = 0;
	for(int i = 30;i >=0 ;--i)
	{
		int id = 0,flag = 1;
		for(int j = 1;j <= n;++j)
		{
			if((a[j] >> i) & 1)
			{
				if(id)
				{
					flag = 0;
					break;
				}
				id = j;
			}
		}
		if(flag && id)
		{
			ans = id;
			break;
		}
	}
	if(ans)
	{
		printf("%d ",a[ans]);
		for(int i = 1;i <= n;++i)
			if(i != ans)
				printf("%d ",a[i]);
	}
	else
		for(int i = 1;i <= n;++i)
			printf("%d ",a[i]);
	return 0;	
}

D - Aerodynamic

思路:n为偶数且对边平行且相等即可,画画图就知道了

#include<bits/stdc++.h>
#define MAXN 100005
#define ll long long
using namespace std;
int n;
ll x[MAXN],y[MAXN];

int main()
{
	scanf("%d",&n);
	for(int i = 0;i < n;++i)
		scanf("%lld%lld",&x[i],&y[i]);
	bool flag = true;
	for(int i = 0;i < n;++i)
	{
		if(abs(x[(i+1)%n] - x[i]) == abs(x[(i+1+n/2)%n] - x[(i+n/2)%n]) && abs(y[(i+1)%n] - y[i]) == abs(y[(i+1+n/2)%n] - y[(i+n/2)%n]));
		else
		{
			flag = false;
			break;
		}
	}
	if((n&1) || !flag)
		printf("NO\n");
	else
		printf("YES\n");
	return 0;
}

E - Water Balance

见:https://blog.csdn.net/xing_mo/article/details/104272740

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值