POJ1323------Game Prediction

来源:互联网 发布:2017淘宝达人登录入口 编辑:程序博客网 时间:2024/04/30 15:41

问题描述:

Game Prediction
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 9680 Accepted: 4626
Description


Suppose there are M people, including you, playing a special card game. At the beginning, each player receives N cards. The pip of a card is a positive integer which is at most N*M. And there are no two cards with the same pip. During a round, each player chooses one card to compare with others. The player whose card with the biggest pip wins the round, and then the next round begins. After N rounds, when all the cards of each player have been chosen, the player who has won the most rounds is the winner of the game. 






Given your cards received at the beginning, write a program to tell the maximal number of rounds that you may at least win during the whole game. 
Input


The input consists of several test cases. The first line of each case contains two integers m (2?20) and n (1?50), representing the number of players and the number of cards each player receives at the beginning of the game, respectively. This followed by a line with n positive integers, representing the pips of cards you received at the beginning. Then a blank line follows to separate the cases. 


The input is terminated by a line with two zeros. 
Output


For each test case, output a line consisting of the test case number followed by the number of rounds you will at least win during the game. 


Sample Input


2 5
1 7 2 10 9


6 11
62 63 54 66 65 61 57 56 50 53 48


0 0
Sample Output


Case 1: 2

Case 2: 4


解法:

这道题目的原理特别简单,就一句话。因为要求A的最少赢的次数,而赢的条件是A所出的牌的数字是最大的,我们只要求出比A所有的牌大的拍的数量(不能重复,比如说,A有对于A的两张牌,2,3,对方有4,4比2大,也比3大,但由于一张牌只能算一次,所以只要从比A所有的最小的那张牌开始计算,并且吧重复的去掉就可以了)。(*)对这种假设做了处理

#include<iostream>#include<fstream>#include<cstdlib>using namespace std;ifstream fin("C:\\data41.in");int m,n;int pip[1001];int search(int min){int cnt=0;for(int num=min+1,pos=min;num<=n*m&&pos<=n*m;++pos,++num){while(pip[pos]!=1&&pos<=n*m)                 (*)++pos;while(!(num>pos&&pip[num]==0)&&num<=n*m)     (*)++num;++cnt;}return n-cnt+1;}int main(){int p,cnt;cnt=0;int min=32797;while(fin>>m>>n&&m!=0&&n!=0){memset(pip,0,sizeof(pip));for(int j=0;j<n;++j){fin>>p;min<?=p;pip[p]=1;}cout<<"case "<<++cnt<<":"<<search(min)<<endl;}system("pause");return 0;}


有了上面的解法,我有对这个算法做出了改进,可以直接算答案了。

这个改进后的算法和改进前的算法的原理是一样的,(**)中的三元运算对上面的假设做出处理。但由于上面的算法有一个标记数组,而这个改进后的算法没有标记数组,所以要先对A手中的牌进行排序,然后才可以用上面的原理来算。

#include<iostream>#include<fstream>#include<cstdlib>using namespace std;ifstream fin("C:\\data41.in");int m,n;int pip[50];void sort(){for(int i=1;i<n;++i){int temp;for(int j=i;j>0;--j){if(pip[j]<pip[j-1]){temp=pip[j];pip[j]=pip[j-1];pip[j-1]=temp;}}}}int DP(){int cnt=0;for(int i=1;i<n;++i){int sub=pip[i]-pip[i-1]-1;cnt=(cnt+sub<i)?(cnt+sub):i;           (**)}int sub=m*n-pip[n-1];cnt=(cnt+sub<n-1)?(cnt+sub):(n-1);             (**)return n-cnt;}int main(){int cnt=0;while(fin>>m>>n&&m!=0&&n!=0){for(int i=0;i<n;++i)fin>>pip[i];sort();int minmax=DP();cout<<"case "<<++cnt<<":"<<minmax<<endl;}system("pause");return 0;}


这个改进后的算法既节约空间,有减少了运算量。

0 0
原创粉丝点击