"Accordian" Patience (UVa 127) 双向链表 栈

题目:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=63

思路:

  从第一个牌堆开始,向右进行遍历。若存在左边第三个牌堆,则优先考虑能否移动到左边第三个牌堆,若不存在或不能移动,再考虑左边第一个牌堆,若都不能移动,则继续考虑下一个牌堆。由于“如果有多张牌可以移动,先移动最左边的牌”,因此进行移动操作以后,要从移动到的那张牌堆开始考虑。每次移动操作都进行牌堆是否为空判断。

PS: 不知道为什么,用 cout 输出的话,一提交就 WA,改成 printf 就AC了,活生生卡了2天。

代码:

#include <iostream>
#include <stack>
#include <cstdlib>
using namespace std;

const int MAX = 53;

struct Node{
    stack<string> stk;
};

int r[MAX], l[MAX];    //结点的右边、左边
Node node[MAX];                //牌堆 

void link(int a, int b);    //连接两个结点
void deleteNode(int a);        //删除结点
void init();                //初始化链表
bool canMove(int a, int b);    //判断能否将 b 的牌顶移到 a
void move(int a, int b);    //将 b 顶部的牌移到 a 牌堆
void check(int a);            //如果 a 的牌堆为空,删除
int treblePre(int a);        //a 前面第三个结点,若不存在,返回 0
bool input();                //输入,若结束返回 false
void output();                //输出 

int main(){

    //freopen("input.txt", "r", stdin);

    while(input()){

        int i=r[0];
        while(i != 0){    //一直做到没有后继

            int pre1 = treblePre(i);    //前面第三个牌堆
            int pre2 = l[i];            //前面第一个牌堆 

            if(pre1 != 0){        //如果前面第三个牌堆存在
                if(canMove(pre1, i)){
                    move(pre1, i);        //就进行移动
                    check(i);            //若为空,删除
                    i = pre1;            //从 pre1 牌堆开始考虑
                    continue;
                }
            }

            if(pre2 != 0){
                if(canMove(pre2, i)){
                    move(pre2, i);        //就进行移动
                    check(i);            //若为空,删除
                    i = pre2;            //从 pre2 牌堆开始考虑
                    continue;
                }
            }

            i = r[i];                    //如果不能移动,则考虑下一堆 

        }

        output();        //输出
    }

    return 0;

}

void link(int a, int b){
    r[a] = b;
    l[b] = a;
} 

void deleteNode(int a){
    link(l[a], r[a]);
} 

void init(){
    for(int i=0; i<MAX-1; i++){            //初始化链
        link(i, i+1);
    }
    r[52] = 0;
}

bool canMove(int a, int b){

    string s1 = node[a].stk.top();
    string s2 = node[b].stk.top();

    if(s1[0] == s2[0] || s1[1] == s2[1]){
        return true;
    }

    return false;

} 

void move(int a, int b){

    node[a].stk.push(node[b].stk.top());
    node[b].stk.pop();

} 

void check(int a){

    if(node[a].stk.empty()){
        deleteNode(a);
    }

}

bool input(){

    string s[MAX];
    init(); 

    cin >> s[1];
    if(s[1] == "#")        //结束返回 false
        return false;

    for(int i=2; i<MAX; i++){
        cin >> s[i];
    }

    for(int i=1; i<MAX; i++){
        node[i].stk.push(s[i]);
    }

}

int treblePre(int a){

    int b = a;

    for(int i=1; i<=3; i++){
        b = l[b];
        if(b == 0)        //若不存在 返回 0
            return 0;
    }

    return b;

}

void output(){

    int sum;
    int cnt = 0;

    for(int i=r[0]; i!=0; i=r[i]){
        cnt++;
    }

    if(cnt == 1)
        printf("1 pile remaining:");
    else
        printf("%d piles remaining:", cnt);

    for(int i=r[0]; i!=0; i=r[i]){
        sum = 0;
        while(!node[i].stk.empty()){
            node[i].stk.pop();
            sum++;
        }
        printf(" %d", sum);
    }

    printf("\n");

}
时间: 2024-08-08 20:57:12

"Accordian" Patience (UVa 127) 双向链表 栈的相关文章

``Accordian&#39;&#39; Patience UVA 127

说说: 这道题难度其实并不但,但是比较繁琐,且细节容易被忽略.先分析一下游戏规则吧,知道游戏规则之后,问题自然而然就解决了.首先放着一行52个扑克牌堆(ps:输入的时候分两行输入)开始每堆只有一张牌,然后从左到右开始判断,若一张牌和左边第一张牌或者左边第三张牌的大小或者花色相同,则将该张牌放到那一对牌之上并且要求继续向左匹配,直到不能匹配为止.若某个堆一张牌都不剩了,则该堆不存在了,也就是说如果两堆相邻,则两堆的牌数都不能为0.最后按照这个规则,直到没有牌能够移动位置.(ps:移动是指顶层牌的移

&quot;Accordian&quot; Patience UVA 127 (”手风琴“牌游戏)

"Accordian" Patience From:UVA, 127 Submit Time Limit: 3000 MS You are to simulate the playing of games of ``Accordian'' patience, the rules for which are as follows: Deal cards one by one in a row from left to right, not overlapping. Whenever th

ACM学习历程——UVA 127 &quot;Accordian&quot; Patience(栈;模拟)

Description  ``Accordian'' Patience  You are to simulate the playing of games of ``Accordian'' patience, the rules for which are as follows: Deal cards one by one in a row from left to right, not overlapping. Whenever the card matches its immediate n

uva 127 &quot;Accordian&quot; Patience(手风琴纸牌)

用 栈 stack 来处理. 直接根据题目描述写就可以.不要忘记每组数据最后的清空栈堆. 题目大意: 给定52张的扑克牌,现在要求对扑克牌进行整理,对于每一张扑克牌,如果左边的第三张存在那么就去判断这一张是否和第三张满足花色或卡片值相同,如果满足则把这一张移动到左边的第三张,否则去判断左边的第一张是否和这一张满足条件:如果左边的第三张不存在那么只要去判断左边的第一张即可.最后输出剩下的扑克牌的堆数,并且输出每一堆的牌数. #include<stdio.h> #include<iostre

Uva 127 poj 1214 `Accordian&#39;&#39; Patience

 ``Accordian'' Patience  You are to simulate the playing of games of ``Accordian'' patience, the rules for which are as follows: Deal cards one by one in a row from left to right, not overlapping. Whenever the card matches its immediate neighbour on

UVa 127 - &quot;Accordian&quot; Patience POJ 1214 链表题解

UVa和POJ都有这道题. 不同的是UVa要求区分单复数,而POJ不要求. 使用STL做会比较简单,这里纯粹使用指针做了,非常麻烦的指针操作,一不小心就错.调试起来还是非常费力的 本题理解起来也是挺费力的,要搞清楚如何模拟也不容易啊,读题要很仔细. 纯指针的操作挺快的吧.不过POJ 0ms,而UVa就0.2左右了. 三相链表: 1 只要有叠起来的牌,那么就使用一个down指针指向下面的牌就可以了. 2 使用双向链表,可以方便前后遍历. 3 记得有了更新牌之后,又要重新开始检查是否需要更新牌,这是

UVa OJ 127 - &quot;Accordian&quot; Patience (“手风琴”纸牌)

UVa OJ 127 - "Accordian" Patience ("手风琴"纸牌) Time limit: 3.000 seconds 限时:3.000秒 Problem 问题 You are to simulate the playing of games of "Accordian" patience, the rules for which are as follows: 模拟玩一个"手风琴"纸牌游戏,规则如下: D

ACM学习历程——UVA127 &quot;Accordian&quot; Patience(栈, 链表)

Description  ``Accordian'' Patience  You are to simulate the playing of games of ``Accordian'' patience, the rules for which are as follows: Deal cards one by one in a row from left to right, not overlapping. Whenever the card matches its immediate n

uva ``Accordian&#39;&#39; Patience

题目如下: ``Accordian'' Patience You are to simulate the playing of games of ``Accordian'' patience, the rules for which are as follows: Deal cards one by one in a row from left to right, not overlapping. Whenever the card matches its immediate neighbour