贪心 hdu-1338-Game Prediction

来源:互联网 发布:sql默认地址不详设置 编辑:程序博客网 时间:2024/03/28 16:23
题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=1338

题目意思:

有m个人,每个人有n张牌,牌点为在1~n*m中的不同的数。每回合每个人出一张牌,点数最大的那个人赢,给出A人初始时的n张牌的牌点,问A至少赢的次数。

解题思路:

其他人要想赢得最多,肯定赢A中牌点小的容易,而只要有一个人的牌点大于A牌点就行,此时可以把小牌都出掉。

所以先按A的牌点排序,依次找到大于A的牌点的最小的没出的牌点,然后在出掉较小的m-2张牌。如果连A中较小的牌点都不能赢,后面的肯定不能赢。

这样就达到了,赢得最实算。这就是本题的贪心思想。

代码:

#include<iostream>#include<cmath>#include<cstdio>#include<cstdlib>#include<string>#include<cstring>#include<algorithm>#include<vector>#include<map>#include<set>#include<stack>#include<list>#include<queue>#define eps 1e-6#define INF 0x1f1f1f1f#define PI acos(-1.0)#define ll __int64#define lson l,m,(rt<<1)#define rson m+1,r,(rt<<1)|1//#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;/*freopen("data.in","r",stdin);freopen("data.out","w",stdout);*/int my[60];bool vis[1100];int main(){   int n,m,ca=0;   while(scanf("%d%d",&m,&n)&&m+n)   {      memset(vis,false,sizeof(vis));      for(int i=1;i<=n;i++)      {         scanf("%d",&my[i]);         vis[my[i]]=true;      }      sort(my+1,my+n+1); //按自己手上的牌,从大到小排序      //如果其他人能赢,则只要有一张牌超过自己手上牌就行了,这时可以丢掉其他的小牌      //当没有比自己大的牌时,后面的一定自己赢了      int pos=1,ans=0;      for(int i=1;i<=n;i++)      {         int tt=my[i],j;         for(j=tt+1;j<=n*m;j++) //找到一张没出的比自己最靠近的大牌            if(!vis[j])            {               vis[j]=true;               break;            }         if(j>n*m) //找不到后面肯定自己赢         {            ans=n-i+1;            break;         }        if(m==2) //其他人已经出完了           continue;        for(int k=0;;) //其他人出较小的牌        {           if(!vis[pos])           {              vis[pos]=true;              k++;           }           pos++;           if(k>=m-2)              break;        }      }      printf("Case %d: %d\n",++ca,ans);   }   return 0;}