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;
  }
}




posted @ 2013-07-22 03:00  814jingqi  阅读(180)  评论(0编辑  收藏  举报