hdu 5353 Average(贪心+构造)
2015-08-08 09:16
288 查看
题意:
有n个人组成一个环,相邻的两个人能互相给糖果,对于相邻的两个人而言,只能进行一次操作,要么x给y一个糖果,要么y给x一个糖果,要么不动,问能否经过一定的操作使得每个人的糖果数一样,并输出步骤。解析:
很显然,如果当前的和sum不能被n除尽,那么肯定不能均分所以这种情况是”NO”。然后可以计算出每个人的糖果,如果某人糖果和平均值的差距的绝对值>=2,那么也不可能平均分配。因为每条边只能走一次,而且每次只能给一个糖果,如果不管怎么索要,怎么给予,至多给2个,所以差距的绝对值>=2这种情况也是非法的。
然后就是判断环的情况,找到第一个> 0的人让他分发糖果,这时可以朝着前后两个方向走,两个方向都判断一次,如果第一个是>=2的,那么就分配给后面一个人一个糖果。
枚举前一个人对后一个人的三种操作,
然后这样第i个人必然对第i+1个人按照
1.少一个糖果就从下一个人手中拿一个
2.多一个就给一个给下一个人
然后判断最后的差距是否都是=0的,如果不是这种情况是false的。
mymy codecode
[code]#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <vector> #define pb push_back typedef long long ll; using namespace std; const int N = 1e5 + 10; struct Node { int a, b; Node(int a, int b) : a(a), b(b) {} }; vector<Node> ans; int n; ll sum; int A , a ; bool run(int dir, int st) { ans.clear(); memcpy(a, A, sizeof(A)); int flag = 0; int u, v; if(a[st] == 2) { u = st; v = (st - dir + n) % n; a[u]--, a[v]++; ans.pb(Node(u, v)); flag = 1; } for(int i = 0; i < n - flag; i++) { u = (st + i*dir + n) % n; v = (st + (i+1)*dir + n) % n; if(a[u] > 0) { a[u]--, a[v]++; ans.pb(Node(u, v)); }else if(a[u] < 0) { a[u]++, a[v]--; ans.pb(Node(v, u)); } if(abs(a[v]) >= 2) return false; } for(int i = 0; i < n; i++) { if(a[i]) return false; } return true; } bool solve() { sum /= n; for(int i = 0; i < n; i++) A[i] -= sum; for(int i = 0; i < n; i++) if(abs(A[i]) > 2) return false; if(n == 2 && abs(A[0]) >= 2) { return false; } for(int i = 0; i < n; i++) { if(A[i] > 0) { if(run(-1, i)) return true; if(run(1, i)) return true; return false; } } return true; } int main() { int T; scanf("%d", &T); while(T--) { ans.clear(); sum = 0; scanf("%d", &n); for(int i = 0; i < n; i++) { scanf("%d", &A[i]); sum += A[i]; } if(sum % n != 0) { puts("NO"); continue; } if(!solve()) { puts("NO"); }else { puts("YES"); printf("%d\n", (int)ans.size()); for(int i = 0; i < ans.size(); i++) printf("%d %d\n", ans[i].a+1, ans[i].b+1); } } return 0; }
相关文章推荐
- linux系统非ROOT用户80端口不能启动tomcat问题的变通办法——通过Iptables端口转发
- Android利用activity启动模式退出整个应用
- STL容器的共通能力和共通操作
- 4 IoC容器的依赖注入(2)
- 【Win 10应用开发】实现全屏播放的方法
- 【Win10 应用开发】OCR识别
- 【Win10应用开发】协议-下篇:自定义多个协议
- 【Win10 应用开发】解决VS 2015 RC不能调试手机应用的问题
- php 生成饼状图,折线图,条形图 通用类
- c#中如何在cshtml页面实现js调用cs变量(mvc模式)
- 树莓派2引脚
- hdu 4612 Warm up (手动扩栈,求树上哪两个点的距离最远)
- 【Win 10开发】协议-上篇:自定义应用协议
- 【Win10 开发】读取PDF文档
- 背包九讲(转载)
- 【Win 10应用开发】SplitView控件
- 【Win 10应用开发】SplitView控件
- Java中的正则表达式
- Summary for week4
- 【Win 10应用开发】认识一下UAP项目