您的位置:首页 > 其它

UVALive 5986解题报告

2015-08-19 18:44 573 查看
You are the organizer of a Wizarding Duel tournament at Hogwarts. N players participated in the

tournament and each player played with every other player exactly once, and each such game resulted

in a winner and a loser (no drawn games). It is now time to declare the results. Each player's score is

the number of games the player won. However, you realize that something possibly went wrong with

the scoring system, and the scores that you have noted down might be wrong. In fact, the scores you

have noted down could simply not be possible. For example, suppose there are 3 players and the scores

that you noted are 0,0 and 2. Clearly this is not possible as the game between the rst two players

must have had a winner and thus both the players cannot have score 0.

While you have no way to gure out the correct scores of each player, you've decided to set the

scores right by adjusting the scores of some players. The new set of scores should be possible to have

arisen in the tournament, otherwise there would be ample proof that the scoring is wrong. However,

making drastic changes might cause suspicion. So you've decided to adjust the scores so that the sum

of the absolute differences between the old and the new scores of each player is minimized. In other

words, if the original scores which you noted are a1, . . . , aN, you must change them to the series of

possible scores b1, . . . . bN such that the sum |ai-bi| is minimized.

Input

The rst line contains the number of test cases T. T test cases follow. Each case contains an integer

N on the rst line, followed by the set of scores which you have noted down: a1 : : : aN.

Output

Output T lines, one for each test case, containing the minimum sum of absolute values in order to make

the scorecard a valid one.

Constraints:

• 1  T  200

• 2  N  50

• 0  ai  100

Sample Input

2

3

0 0 2

5

5 3 2 1 4

Sample Output

1

5

题目意思就是N个人比赛,赢得得1分,输的得0分,没有平局。但最后分数记录出错,要你推算出正确的一个分数与这个错误的分数对应编号的差的绝对值的最小值。

比如的一个例子:不可能有两个0,肯定有一个1,因为他们两个之间比试有个人会赢。所以可能正确的分数为1 0 2(1-0=1;0-0=0;2-2=0)所以正确分数与错误分数对应编号的差的绝对值的最小值为1。

现在我们来看第二组,5个人,可能的一组正确数据为43210。这组数据很特殊,因为它每个数都是取了之前的数后,当下能取的最大的数。比如刚开始,最大能取4,第二个人最大只能取3了,因为他输给了前面那个人。所以我们可以得出一个结论,那就是把的分按从小到大排序后,第一个人得分要>=0,前两个人要>=1,前三个要>=3。。由43210可知因为前面每次都是取当前最大值,所以后面剩下的n个人的得分就是n个人所能的到的最少分数。

理解了这个,做起来就easy了。只要给分数排个序,依次1,2,3,。。。个人取下去,若到第x个人时,比最低分数少了,则补上 d(补上的人数)= min(最低分)-p(当前有多少分) sum1(输入的分数的和)+=d (补上的人数) ans(答案变量)+=d(补上的人数)。。。最后可能会比正确得分的总分数高,ans+=sum1-sum(得分正确时的得分 为常数)

#include<iostream>

#include<cstdio>

#include<cstring>

#include<cstdlib>

#include<cmath>

#include<algorithm>

#include<stack>

#include<queue>

#include<vector>

#include<set>

#include<map>

using namespace std;

int T,N;

int a[101],sum1,sum2,ans;

int book[101];

int main()

{

while(cin>>T)

{

while(T--)

{

memset(book,0,sizeof(book));

sum1=sum2=ans=0;

cin>>N;

if(N%2) sum1=((N-1)/2)*N;

else sum1=(N/2)*(N-1);

for(int i=0;i<N;i++)

{

scanf("%d",&a[i]);

//sum2+=a[i];

if(i)

book[i]+=(book[i-1]+i);

}

sort(a,a+N);

for(int i=0;i<N;i++)

{

sum2+=a[i];

if(sum2<book[i])

{

ans+=(book[i]-sum2);

sum2=book[i];

}

}

cout<<ans+abs(sum1-sum2)<<endl;

}

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: