您的位置:首页 > 其它

2015多校第6场 HDU 5353 Average 贪心,细节处理

2017-08-10 10:03 369 查看

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5353

题意:有n个人围城一个环,每一个人手里都有一些糖果,第i个人有ai块。现在有三种操作:第i个人给第i+1个人一块。第i+1个人给第i个人一块。什么都不做。第i个人和第i+1个人之间,可以选择一种操作并执行,问最终能不能让所有人手里的糖相等。

解法:贪心。

当n = 1 时,永远是YES

当n = 2 时,注意1和2之间只能有一种操作,不存在循环。

当n > 2 时:

糖的总数不能均分到n个人手中,直接NO

可以分开,存在一个循环,那么枚举第1个人对第2个人的操作,那么对于第2个人及以后的人来说它的左侧已经确定了,那么它为了维护自己的糖数是平均值,只能对下一个人进行操作,如果当前比平均值少1,那么从下一个人手里拿一个,如果正好,那么不操作,如果多一个,那么给下面的人一个,其他情况都是无解的。

注意:在操作时,要保证它当前有糖。所以要判断一下。

 

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+6;
typedef long long LL;
int a[maxn], ans[maxn];

int main()
{
int T, n;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
LL sum = 0, ave = 0;
for(int i=0; i<n; i++){
scanf("%d", &a[i]);
sum += a[i];
}
bool flag = 1;
int num;
ave = sum/n;
memset(ans, 0, sizeof(ans));
if(sum%n){
flag = 0;
}
else if(n == 2){
if(abs(a[0]-ave) >= 2) flag = 0;
else if(abs(a[0]-ave)){
ans[0]=a[0]>a[1]?1:-1;
}
}
else if(n>2){
int i,j,k;
for(i=-1; i<=1; i++){
ans[0]=i;
for(j=1; j<n; j++){
k=a[j]+ans[j-1];
if(k==ave) ans[j]=0;
else if(k+1==ave){
if(a[(j+1)%n]) ans[j]=-1;
else break;
}
else if(k-1==ave){
ans[j]=1;
}
else break;
}
if(j==n&&a[0]-ans[0]+ans[n-1]==ave) break;
}
if(i==2) flag = 0;
}
if(flag==0){
puts("NO");
}
else{
puts("YES");
num = 0;
for(int i=0; i<n; i++) if(ans[i]) num++;
printf("%d\n", num);
for(int i=0; i<n; i++){
if(!ans[i]) continue;
int u = i+1;
int v = (i+1)%n+1;
if(ans[i]==-1) swap(u, v);
printf("%d %d\n", u, v);
}
}
}
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: