127 - "Accordian" Patience

题目:127 - "Accordian" Patience


题目大意:给52张牌,要求从左到右判断第i张牌和第i- 3,或是 i- 1 是否存在数字或是花色相同的话(先考虑i- 3),相同就将这张牌移到相同的那张牌的位置,每个位置不一定只有一张牌,但只有最上面的牌可以移动。

解题思路:为了保证只有最上面的牌可以移动用到栈,为了让后面的牌移动到前面没有牌的位置,用到链表。 先判断第i- 3 张牌,相同移动。不同的话换i- 1,相同移动,不同i++。如果判断相同,i就要等于被改变的位置,因为这里的第一张牌被改变了所以要重新判断。直到没有牌可以移动,顺利的判断到最末尾既可以结束了。


#include<stdio.h>
#include<stack>
using namespace std;

const int N = 55;


struct st{

	stack <char> v, c;
	st *p;
} * head = NULL , * move = NULL;

st* find(int n) {  //寻找前n个

	st* f = head;
	if(n < 0)
		return NULL;
	for(int i = 0; i < n; i++)
		f = f ->p;
	return f;
}

int main() {
	
	while(1) {

		int i;
		char ch[5];
		scanf("%s", &ch);
		if(ch[0] == '#')
			break;
		head = new st();
		head -> v.push(ch[0]);
		head -> c.push(ch[1]);
		head -> p = NULL;
		move = head;
		for (i = 1; i < 52; i++) {
			
			scanf("%s", &ch);
			move -> p = new st();
			move -> p -> v.push(ch[0]);
			move -> p -> c.push(ch[1]);
			move -> p -> p = NULL;
			move = move -> p;
		
		}
		//从第二个开始找
		move = head -> p;
		i = 1;		
		while(move != NULL){

			char A, B, C, D;
			st* L2 = find(i - 3);
			st* L1 = find(i - 1);
			if(L2 != NULL){
				
				A = move -> v.top();
				C = move -> c.top();
				B = L2 -> v.top();
				D = L2 -> c.top();
				if(A == B || C == D) {

						move ->v.pop();  //删除第一张牌
						move ->c.pop();
						L2 ->v.push(A);  //移动牌
						L2 ->c.push(C);
				
						
					if(move -> v.empty()) {
						
						L1 -> p = move -> p;  //将move从链表中移除
						delete move;
					}
					i = i - 3;
					move = L2;   //有移动牌就从移动到的位置开始
					continue;
				}
			
			}
			if(L1 != NULL){

				A = move -> v.top();
				C = move -> c.top();
				B = L1 -> v.top();
				D = L1 -> c.top();
				if(A == B || C == D) {

						move ->v.pop();
						move ->c.pop();
						L1 ->v.push(A);
						L1 ->c.push(C);
				
						
					if(move -> v.empty()) {
						
						L1 -> p = move -> p;
						delete move;
					}
					i = i- 1;
					move = L1;
					continue;
				}
			
			}
	
				i++;    //都没有移动的话,判断下一张牌
				move = move -> p;
		}
		int count = 0;
		for(move = head; move != NULL ; move  = move -> p)
			count++;
		if(count > 1)
		printf("%d piles remaining:", count);
		else
			printf("%d pile remaining:", count);
		for(move = head; move != NULL ; move  = move -> p) {

			printf(" %d", move -> v.size());
		}
		printf("\n");
	
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值