2013金山西山居创意游戏程序挑战赛——初赛(2) C 卡片游戏 (hdu 4550 )

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

题意:

小明最近宅在家里无聊,于是他发明了一种有趣的游戏,游戏道具是N张叠在一起的卡片,每张卡片上都有一个数字,数字的范围是0~9,游戏规则如下:
  首先取最上方的卡片放到桌子上,然后每次取最上方的卡片,放到桌子上已有卡片序列的最右边或者最左边。当N张卡片全部都放到桌子上后,桌子上的N张卡片构成了一个数。这个数不能有前导0,也就是说最左边的卡片上的数字不能是0。游戏的目标是使这个数最小。
  现在你的任务是帮小明写段程序,求出这个最小数。


思路:很明显的贪心题,首先若没有前导0的限制,则我们每次取出一个数,它和已经取出的数中最左边的数相比,若大于它,显然我们应该将它放在右边,否则我们应该将它放左边。但是现在有了前导0的限制,则按照上面的策略就会出现非法解。事实上,由于最左边的数不能是0,所以我们得到的数的位数是一定的,在这种情况下要得到最小的数,显然就是要让前边的尽量小。则我们可以按照下列策略进行取舍

我们设当前取出的数的最左边的数为tmp,初始化为0.

接下来我们一个一个从上往下卡片。

1.若我们遇到了0,则我们看需找还没取过的数中的最小值(设为mi)是否小于或等于tmp,若成立,则我们把0放到左边,并将tmp设为mi。并找到还未等于mi的数中最地下那个数的位置(设为po)。

2.若我们遇到了非0,则有两种情况

(1)如果我们当前取出的数中最左边的数不为0,则按照上面红字所示的贪心方法即可。

(2)否则,我们看当前取出的这个数是否就是1中所找到的那个数(位置为po),若是我们将它放到左边,否则放到右边。

这个方法的核心就是要保证最后得到的数左边的数尽量小。上述描述还有一些细节没有描述出来,具体实现请参考我的代码。


代码如下:

#include 
#include 
#include 
#include 
using namespace std;
char str[110];
int vis[220];
int main()
{
   //freopen("dd.txt","r",stdin);
   int ncase;
   scanf("%d",&ncase);
   while(ncase--)
   {
       scanf("%s",str);
       int i,len=strlen(str);
       int min[110];
       min[len-1]=str[len-1]=='0'?10:str[len-1]-'0';
       for(i=len-2;i>=0;i--)
       {
           if(str[i]-'0'==0)
           min[i]=min[i+1];
           else if(str[i]-'0'




你可能感兴趣的:(其他,比赛题解)