您的位置:首页 > 其它

UVa 127: "Accordian" Patience

2013-08-01 19:36 405 查看
这题只是一道简单的模拟题而已(真的只是简单而已 =-= 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: