题目链接:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=63
题目描述:
给一副牌,开始有52堆,然后执行匹配合并操作,如果某一堆最上面的牌与左边的第三堆或第一堆牌最上面的牌匹配,则将这张牌合并到匹配的那一堆上。如此一直做直到只剩下一堆或者不能做为止。注意如果有两张牌都可以做合并操作,先做最左边的,如果一张牌可以与左边的第一堆和第三堆做合并操作,则先执行与第三堆的操作。匹配规则:花色相同或者数值相同。
解题思路:
注意合并后要重新从合并后的后面一堆开始处理。
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#define eps 1e-6
#define INF (1<<20)
#define PI acos(-1.0)
using namespace std;
struct Inf
{
char save[55][5];
int top;
}inf[55];
bool judge(int a,int b)
{
int topa=inf[a].top,topb=inf[b].top;
if(inf[a].save[topa][0]==inf[b].save[topb][0])
return true;
if(inf[a].save[topa][1]==inf[b].save[topb][1])
return true;
return false;
}
void remove(int m)
{
for(int i=m+1;i<=52;i++) //删除当前的第m个
{
if(inf[i].top==0) //已经到了最后
return ;
inf[i-1]=inf[i];
inf[i].top=0; //后面的置空
}
}
int main()
{
char temp[5];
int ans[55];
while(scanf("%s",temp)&&*temp!='#')
{
strcpy(inf[1].save[1],temp);
inf[1].top=1;
for(int i=2;i<=52;i++)
{
scanf("%s",inf[i].save[1]);
inf[i].top=1;
}
int len=52;
for(int i=2;i<=52;)
{
if(inf[i].top==0)
break;
if(i>=4&&judge(i-3,i))
{
inf[i-3].top++;
strcpy(inf[i-3].save[inf[i-3].top],inf[i].save[inf[i].top]);
inf[i].top--;
if(inf[i].top==0)
{
remove(i); //把所有的空全部放到后面
len--;
}
i-=3; //相当于往前移3个
}
else if(i>=2&&judge(i-1,i))
{
inf[i-1].top++;
strcpy(inf[i-1].save[inf[i-1].top],inf[i].save[inf[i].top]);
inf[i].top--;
if(inf[i].top==0)
{
remove(i);
len--;
}
i-=1;
}
else
i+=1;
}
printf("%d ",len);
len>1?printf("piles "):printf("pile ");
printf("remaining:"); //注意单复数
for(int i=1;i<=len;i++)
printf(" %d",inf[i].top);
putchar('\n');
}
return 0;
}