这个题在早的时候就不会做。后来中间想清楚了是个模拟,尝试写了好多次一直都没过样例。今天又重写,还是没过。。。
后来看题,发现是题意读错了。
1.先移动左边可以移动的。2.如果该牌左三和左一同时可以移动,先移动左三。
我一直都忽略了第一个条件了,一直都是从右往左移动,结果一直都不对。。
侥幸过了样例以后交上去TLE。
确实,各种重复,代码超渣。。
最后改掉了STL,自己写了个stack;string改换成char[]。
最后2.2s水过。。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
struct Stack
{
char card[60][4];
int num;
void clear()
{
memset(card,0,sizeof(card));
num=0;
}
};
Stack arr[60];
int len;
inline bool Match(Stack a,Stack b)
{
int &ta=a.num,&tb=b.num;
if(!ta||!tb) return false;
if(a.card[ta][0]==b.card[tb][0]||a.card[ta][1]==b.card[tb][1]) return true;
return false;
}
inline int Adjust(int l)
{
int ll=0;
for(int i=0; i<l; ++i)
{
int temp=arr[i].num;
if(temp)
{
for(int j=1; j<=temp; ++j)
strcpy(arr[ll].card[j],arr[i].card[j]);
arr[ll++].num=temp;
}
}
return ll;
}
bool update;
inline void Move(Stack &a,Stack &b)
{
update=true;
int &ta=a.num,&tb=b.num;
strcpy(a.card[++ta],b.card[tb]);
--tb;
}
int main()
{
char str[4];
while(scanf("%s",str)&&strcmp(str,"#"))
{
for(int i=0; i<52; ++i)
arr[i].clear();
strcpy(arr[0].card[++arr[0].num],str);
for(int i=1; i<52; ++i)
{
scanf("%s",str);
strcpy(arr[i].card[++arr[i].num],str);
}
len=52;
int pos=0;
while(1)
{
update=false;
for(int i=pos; i<len; ++i)
{
if(i-3>=0&&Match(arr[i-3],arr[i]))
{
Move(arr[i-3],arr[i]);
pos=i-3;
break;
}
else if(i-1>=0&&Match(arr[i-1],arr[i]))
{
Move(arr[i-1],arr[i]);
pos=i-1;
break;
}
}
len=Adjust(len);
if(!update) break;
}
if(len==1) puts("1 pile remaining: 52");
else
{
printf("%d piles remaining:",len);
for(int i=0; i<len; ++i)
printf(" %d",arr[i].num);
printf("\n");
}
}
return 0;
}