这题只是一道简单的模拟题而已(真的只是简单而已 =-= T^T),虽然我花了好长时间。
我使用数组模拟链表,模拟对纸牌的操作。
要注意的是堆剩余数为1时,输出的不是“piles",而是"pile"。
我的解题代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <string>
#include <algorithm>
using namespace std;
char Rank[55],Suit[55];
int Next[55],L[55],R[55],Num[55]; //Next[i]存放纸牌i下方的纸牌编号,L,R存放i的左右堆上第一张牌,Num存放i所在堆的纸牌数
int piles_remain; //堆剩余数
void move(int i, int j)
{//将以编号为i的的纸牌移动到编号为j的纸牌上方
if(Next[i]==-1) //移动前i的下面没有其他牌
{
R[L[i]] = R[i];
L[R[i]] = L[i];
piles_remain--;
}
else //移动前i下面有其他牌
{
R[L[i]] = Next[i];
L[R[i]] = Next[i];
L[Next[i]] = L[i];
R[Next[i]] = R[i];
Num[Next[i]] = Num[i]-1;
Num[i] = 1;
}
R[L[j]] = i;
L[R[j]] = i;
L[i] = L[j];
R[i] = R[j];
Next[i] = j;
L[j] = R[j] = -1;
Num[i] += Num[j];
Num[j] = 0;
}
int left1(int s)
{//返回纸牌s左边堆的最上面一张牌编号
return L[s];
}
int left3(int s)
{//返回纸牌s左边第三堆最上面一张牌编号
int c=3,tmp=s;
while(c--)
{
tmp=L[tmp];
}
return tmp;
}
int main()
{
int tmp,count,L1,L3;
while(cin>>Rank[1] && Rank[1]!='#')
{
cin >> Suit[1];
Num[1] = 1;
for(int i=2; i<=52; i++)
{
cin >> Rank[i] >> Suit[i];
Num[i] = 1;
}
memset(Next,-1,sizeof(Next));
for(int i=1; i<=52; i++)
{
R[i] = i+1;
L[i] = i-1;
}
piles_remain = 52;
R[0] = 1;
while(piles_remain>1)
{
int i;
for(i=R[0]; i!=53; i=R[i])
{
L1 = left1(i); L3 = left3(i);
if(L3!=0 && (Rank[i]==Rank[L3] || Suit[i]==Suit[L3]))
{
// cout << i << " -> " << L3 << endl;
move(i,L3);
break;
}
else if(L1!=0 && (Rank[i]==Rank[L1] || Suit[i]==Suit[L1]))
{
// cout << i << " -> " << L1 << endl;
move(i,L1);
break;
}
}
if(i==53) break;
}
if(piles_remain==1) cout << 1 << " pile remaining:";
else cout << piles_remain << " piles remaining:";
for(int i=R[0]; i!=53; i=R[i])
cout << ' ' << Num[i];
cout << endl;
}
return 0;
}
浙公网安备 33010602011771号