zoj 2343 Robbers (G)
题目地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2343
题目分析:
1题目大意就是按照预先定好的标准分钱,一个很大的提示就是 y不整除m ,自然想到先用代余除法,把能按照这个方式分的钱分完再说,但是余下的钱仍然可能过比n大不好分
应该是先每个人得到 [ x[i]*k/m ] 这么多钱 ,由高斯函数的性质知余下的钱不会多于n, 最后挑出对整体的 "方案不均匀系数"(即最后要求最小的那个数)影响最小的left个人(还剩left 块钱)
2 注意要点 将每个人放在struct 中,包含id 信息,这样在排序之后还能和原来的序列对应起来
#include<iostream> #include<algorithm> #include<cmath> using namespace std; struct robber { int money; int id; double inf; }; int cmp(robber x,robber y) { if(x.inf<y.inf) return 1; else return 0; } int main() { int size; cin>>size; for(int l=0;l<size;l++) { int n,m,y; cin>>n>>m>>y; int *p=new int [n]; for(int i=0;i<n;i++) cin>>p[i]; int q[n]; for(int i=0;i<n;i++) { q[i]=m*p[i]/y; } int sum=0; for(int i=0;i<n;i++) sum+=q[i]; int left=m-sum; // 存在结构体中去 robber * rr=new robber[n]; for(int i=0;i<n;i++) { rr[i].id=i; rr[i].money=q[i]; rr[i].inf=abs((q[i]+1.0)/m-(p[i]*1.0)/y)-abs((q[i]*1.0)/m-(p[i]*1.0)/y); } sort(rr,rr+n,cmp); for(int i=0;i<left;i++) { q[rr[i].id]++; } for(int i=0;i<n-1;i++) cout<<q[i]<<" "; cout<<q[n-1]<<endl; if(l<size-1) cout<<endl; } }