UVa OJ 127

1、本题,很多人说是水题,我却WA了4次+TLE1次。

2、考察的就是队列+链表。本人一向对链表有恐惧心理,所以打算只用队列蒙混过关,下场是很悲惨的——毫无悬念地TLE了。

3、每堆纸牌可以用数组模拟,数组和数组之间可以用链表模拟,因为会出现空档,如果再搜索中还要处理空档,将会造成巨大的时间浪费。这里的链表不是很“纯正”,因为没有用指针,只用了两个数组left和right,但是还是用到了链式结构的思想——终于省出一大笔时间。

4、最后还是WA,抱着试试看的心理,在函数的&&后面添加了一个大括号,果断AC。原因就是我没有掌握好短路运算符。如果没有括号,那么虽然本意是当两张纸牌的花色相同时,就判断可以移动,但事实上,由于前面对已挪出的纸牌赋值成\0,造成两个都是\0的话也可以移动这种情况,就导致了错误。

5、感慨:AC和爱情一样,总在不经意间悄悄来临,让你措手不及却又欣喜若狂。

#include <stdio.h>
char s[60][110]={""};
int p,i,num[60]={0},flag=1,pile=0,left[60]={0},right[60]={0},temp;
void perform(int i,int j)
{
    if(s[i][num[i]]&&(s[i][num[i]]==s[j][num[j]]||s[i][num[i]+1]==s[j][num[j]+1]))
         {
            num[j]+=2;
            s[j][num[j]]=s[i][num[i]];
            s[j][num[j]+1]=s[i][num[i]+1];
            s[i][num[i]]=s[i][num[i]+1]='\0';
            num[i]-=2;
               if(num[i]==-2)
               {
                left[right[i]]=left[i];
                right[left[i]]=right[i];
               }
            flag=1;
         }
}
int main(void)
{
     num[52]=-2;left[52]=51;left[51]=50;right[51]=52;
    while(1)
    {
       p=0;pile=0;
       while(scanf("%s",s[p])==1)
      {
        if(s[p][0]=='#'||p==51) break;
        else
        {
            left[p]=p-1;
            right[p]=p+1;
            p++;
        }
      }
      if(p==0) break;
      flag=1;
      while(flag)
      {
        flag=0;
        perform(1,0);
        if(flag) continue;
        temp=left[2];
        perform(2,temp);
        if(flag) continue;
        i=3;
         while(i<52)
        {
            while(num[i]<0&&i<52) i++;
            if(num[i]>=0)
            {
               temp=left[left[left[i]]];
               perform(i,temp);
               if(flag) break;
               temp=left[i];
               perform(i,temp);
               if(flag) break;
            }
            if(i!=52)
              i=right[i];
            else
              break;
        }
      }
      for(i=0;i<52;i++)
      if(num[i]>=0) pile++;
      if(pile==1)
          printf("%d pile remaining:",pile);
      else
           printf("%d piles remaining:",pile);
      for(i=0;i<52;i++)
      if(num[i]>=0)
      {
          printf(" %d",(num[i]+2)/2);
      }
      printf("\n");
      memset(s,'\0',sizeof(s));
      memset(num,0,sizeof(num));
      memset(left,0,sizeof(left));
      memset(right,0,sizeof(right));
      num[52]=-2;left[52]=51;left[51]=50;right[51]=52;
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值