HDU 5353 Average(破解环的做法是枚举起始点の操作,灵活题)
2015-11-07 19:03
519 查看
题目链接:点击打开链接(转自:http://www.bubuko.com/infodetail-1024312.html)
题目大意:有n个人围城一个环,每一个人手里都有一些糖果,第i个人有ai块。
现在有三种操作:
第i个人给第i+1个人一块。如果i有
第i+1个人给第i个人一块。如果i+1有
什么都不做。
第i个人和第i+1个人之间,可以选择一种操作并执行,问最终能不能让所有人手里的糖相等。
当n = 1 时,永远是YES
当n = 2 时,注意1和2之间只能有一种操作,不存在循环。
当n > 2 时:
糖的总数不能均分到n个人手中,直接NO
可以分开,存在一个循环,那么枚举第n-1个人对第0个人的操作,那么对于第0个人及以后的人来说它的左侧已经确定了,那么它为了维护自己的糖数是平均值,只能对下一个人进行操作,如果当前比平均值少,那么从下一个人手里拿一个,如果正好,那么不操作,如果多一个,那么给下面的人一个,其他情况都是无解的。
题目大意:有n个人围城一个环,每一个人手里都有一些糖果,第i个人有ai块。
现在有三种操作:
第i个人给第i+1个人一块。如果i有
第i+1个人给第i个人一块。如果i+1有
什么都不做。
第i个人和第i+1个人之间,可以选择一种操作并执行,问最终能不能让所有人手里的糖相等。
当n = 1 时,永远是YES
当n = 2 时,注意1和2之间只能有一种操作,不存在循环。
当n > 2 时:
糖的总数不能均分到n个人手中,直接NO
可以分开,存在一个循环,那么枚举第n-1个人对第0个人的操作,那么对于第0个人及以后的人来说它的左侧已经确定了,那么它为了维护自己的糖数是平均值,只能对下一个人进行操作,如果当前比平均值少,那么从下一个人手里拿一个,如果正好,那么不操作,如果多一个,那么给下面的人一个,其他情况都是无解的。
#include<iostream> #include<algorithm> #include<string> #include<map>//int dx[4]={0,0,-1,1};int dy[4]={-1,1,0,0}; #include<set>//int gcd(int a,int b){return b?gcd(b,a%b):a;} #include<vector> #include<cmath> #include<stack> #include<string.h> #include<stdlib.h> #include<cstdio> #define mod 1000000007 #define ll long long using namespace std; ll x[100005],y[100005]; int n; ll s; vector<pair<int,int> > v; int main(){ int t; scanf("%d",&t); while(t--){ scanf("%d",&n); s=0; for(int i=0;i<n;++i){ scanf("%I64d",&x[i]); s+=x[i]; } int u=0; if(s%n!=0){ printf("NO\n"); continue; } if(n==2){ s/=n; if(x[0]<s){ x[0]++; x[1]--; v.push_back(make_pair(1,0)); } else if(x[0]>s){ x[0]--; x[1]++; v.push_back(make_pair(0,1)); } if(x[0]==s&&x[1]==s) u=1; } else{ s/=n; int k; for(k=1;k<=3;++k){ //k=1时0和n-1不交换,k=2时n-1给0一颗,k=3时0给n-1一颗 for(int j=0;j<n;++j) y[j]=x[j]; v.clear(); if(k==2){ y[0]++; y[n-1]--; v.push_back(make_pair(n-1,0)); } else if(k==3){ y[0]--; y[n-1]++; v.push_back(make_pair(0,n-1)); } for(int i=0;i<n-1;++i){ if(y[i]<s){ y[i]++; y[i+1]--; v.push_back(make_pair(i+1,i)); } else if(y[i]>s){ y[i]--; y[i+1]++; v.push_back(make_pair(i,i+1)); } } int i; for(i=0;i<n;++i){ if(y[i]!=s) break; } if(i==n) break; } if(k!=4) u=1; } if(u==0) printf("NO\n"); else{ printf("YES\n"); printf("%d\n",v.size()); for(int i=0;i<v.size();++i) printf("%d %d\n",v[i].first+1,v[i].second+1); } } return 0; }
相关文章推荐
- Maven之——非法字符: \65279的解决办法
- socket 多线程连接 accept 详解
- WCF 入门(20)
- 使用httpclient框架分别用post,get方式提交
- MySQL高可用方案选型参考
- 近两天的一发新浪微博crsf.exp源码
- poj 1742 Coins dp 多重背包 优化
- init rtl8367
- 《软件需求最佳实践》阅读笔记一
- 卜算子·谒杜甫草堂
- 代理模式
- 字符串操作函数、数学函数
- 三种方式实现自定义圆形进度条ProgressBar
- HDU 5522 Numbers
- 利用粒子群算法求解非线性二层规划问题(matlab)
- python机器学习《入门》
- 图片轮播
- hdu5533Dancing Stars on Me
- 机器学习实战--KNN 算法 笔记
- java多线程细节归纳汇总