您的位置:首页 > 其它

ZOJ 2343 Robbers(思路)

2017-04-20 15:38 330 查看

Robbers

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

ps:能说这道题比赛时做了5个小时吗。。。智商感人啊!

思路:先利用比例求出每一个k[i],然后把k[i]分成整数和小数部分,并计算出总的整数部分的和s,然后按小数部分从大到小排序一下,接着遍历,对整数部分进行+1操作,直到s==m,最后再按原位置输出就好了

代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

#define maxn 1010
struct node
{
int x,pos;
double y;
} q[maxn];
int a[maxn];

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--)
{
int n,m,y;
scanf("%d%d%d",&n,&m,&y);
for(int i=1; i<=n; ++i)
scanf("%d",&a[i]);
double cc=m*1.0/y,tmp;
int sum=0;
for(int i=1; i<=n; ++i)
{
q[i].pos=i;
tmp=a[i]*cc;
q[i].x=(int)tmp;
q[i].y=tmp-q[i].x;
sum+=q[i].x;
}
sum=m-sum;
sort(q+1,q+1+n,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)
printf(i==n?"%d\n":"%d ",q[i].x);
puts("");
}
return 0;
}


总结:果然是我们思路错了。。

看一下我们的思路吧,

算出每一个k[i]=m/y*x[i],先统计有多少个大于x.5的s1,多少个小于x.5的s2,多少个等于x.5的s3,然后遍历,如果是等于x.5的那就一替一个输出上界和下界,如果s1>s2,那么就从大于x.5并且最靠近x.5那里开始,输出他们的下界,直到最后s1和s2相等或相差为1。如果s2>s1,则相反

现在想想当时真是没考虑全面,智商差距啊!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: