ZOJ2343 Robbers(贪心)

来源:互联网 发布:vb mscomctl.ocx 编辑:程序博客网 时间:2024/05/21 11:20

题目:

Robbers Time Limit: 5 Seconds Memory Limit: 32768 KB Special
Judge N robbers have robbed the bank. As the result of their crime
they chanced to get M golden coins. Before the robbery the band has
made an agreement that after the robbery i-th gangster would get Xi=Y
of all money gained. However, it turned out that M may be not
divisible by Y.

The problem which now should be solved by robbers is what to do with
the coins. They would like to share them fairly. Let us suppose that
i-th robber would get Ki coins. In this case unfairness of this fact
is |Xi/Y - Ki/M|. The total unfairness is the sum of all particular
unfairnesses. Your task as the leader of the gang is to spread money
among robbers in such a way that the total unfairness is minimized.

This problem contains multiple test cases!

The first line of a multiple input is an integer N, then a blank line
followed by N input blocks. Each input block is in the format
indicated in the problem description. There is a blank line between
input blocks.

The output format consists of N output blocks. There is a blank line
between output blocks.

Input

The first line of the input file contains numbers N, M and Y (1 <= N
<= 1000, 1 <= M, Y <= 10000). N integer numbers follow - Xi (1 <= Xi
<= 10000, sum of all Xi is Y).

Output

Output N integer numbers - Ki (sum of all Ki must be M), so that the
total unfairness is minimal.

Sample Input

1

3 10 4 1 1 2

Sample Output

2 3 5

Author: Andrew Stankevich Source: Andrew Stankevich’s Contest #2
Submit Status

思路

题目给了Y的值和M的值,然后有n个数据,分别代表x1,x2xn
然后题目问的意思是要使

|x1Y-k1M|+|x2Y-k2M|+…+|xnY-knM|的值最小

让你输出k1,k2,...,kn的值

这里我们要使他们的绝对值最小,那么我们令|xiY-kiM|=0,可以得到ki=MxiY,我们知道MY的值是不变的,所以我们就先求出它。

然后我们把xiMY的值求出来,因为是一个浮点数,所以我们把整数部分和小数部分分别存储,看整数部分的和和M的差距是多少,这时我们用到贪心思路,我们按照小数部粉从大到小排序,然后在那个差距范围里,给xiMY的每一位都+1,这样就可以得出我们要的ki的值,最后按照题目给出的顺序输出就行

代码

#include <cstdio>#include <cstring>#include <cctype>#include <string>#include <set>#include <iostream>#include <stack>#include <cmath>#include <queue>#include <vector>#include <algorithm>#define mem(a,b) memset(a,b,sizeof(a))#define inf 0x3f3f3f3f#define mod 10000007#define debug() puts("what the fuck!!!")#define N 100100#define M 1000000+10#define ll long longusing namespace std;int n,m,y;int a[N];struct node{    int x,pos;    double y;}q[N];bool cmp1(node a,node b){    if(a.y==b.y)        return a.pos<b.pos;    return a.y>b.y;}bool cmp2(node a,node b){    return a.pos<b.pos;}int main(){    int t;    scanf("%d",&t);    while(t--)    {        scanf("%d%d%d",&n,&m,&y);        for(int i=1;i<=n;i++)        {            scanf("%d",&a[i]);        }        double cc=m*1.0/y;        double temp;        int sum=0;        for(int i=1;i<=n;i++)        {            q[i].pos=i;            temp=a[i]*cc;//另他们详见的绝对值=0,然后推出ki=xi*(m/y)            q[i].x=(int)temp;//取整数部分            q[i].y=temp-q[i].x;//取小数部分            sum+=q[i].x;//把整数部分的值加起来        }        sum=m-sum;//整数部分和m的值相差的位数        sort(q+1,q+n+1,cmp1);//小数部分从大到小排序        for(int i=1;i<=n;i++)        {            if(sum)            {                q[i].x++;                sum--;            }        }        sort(q+1,q+1+n,cmp2);        for(int i=1;i<=n;i++)        {            if(i>1)printf(" ");            printf("%d",q[i].x);        }        puts("");    }    return 0;}
0 0
原创粉丝点击