UVa 127 - "Accordian" Patience

来源:互联网 发布:pyrosim软件 编辑:程序博客网 时间:2024/05/18 03:59

传送门UVa 127 - "Accordian" Patience

做的第一题对我来说比较复杂的栈的题目.

题意是这样的:

摆好52张牌, 从左到右搜索, 如果某张牌的前三堆牌或者前一张牌和它的花色or大小相同, 就把它移动到那堆牌的上面.

如果两者都能移动, 就移到前三堆牌处.

当不能再移动的时候, 输出每堆牌的数量.

主要思想是把每个牌堆看成一个栈...然后就各种进栈各种出栈..

参考了别人的代码, 理解了一下.明天再做一遍.

#include <cstdio>using namespace std;typedef struct card{    int num;    char suit[54];    char rank[54];};card stack[54];void Move(int i);void Cover(int step,int i, char nowrank, char nowsuit, int leftnum);int Junge();int main(){    //freopen("input.txt", "r", stdin);    int i, j;    while (true)    {        scanf("%c", &stack[0].rank[0]);        if (stack[0].rank[0] == '#')            break;        scanf("%c", &stack[0].suit[0]);        stack[0].num = 1;        for (i = 1; i < 52; i++)        //读入牌组.        {            getchar();            scanf("%c%c", &stack[i].rank[0], &stack[i].suit[0]);            stack[i].num = 1;        }        int cnt = Junge(); //程序的核心,判断能不能移动, 最后返回的是牌组的数目        if (cnt > 1)            printf("%d piles remaining:", cnt);        else            printf("%d pile remaining:", cnt);        for (i = 0; i < cnt; i++)            printf(" %d", stack[i].num);        printf("\n");        getchar();    }    return 0;}int Junge(){    int i, j, count = 52;    while (true)    {int flag = 0;       //flag的作用是记录一轮搜索下来有没有牌移动,如果没有的话意味着已经无法再移动了.程序结束.        for (i = 0; i < count; i++)        {            int  sflag = 0; //变量,标志前三个位置有没有移动过            char nowsuit, nowrank;            int leftnum, nownum;            nownum = stack[i].num;            nowsuit = stack[i].suit[nownum - 1];            nowrank = stack[i].rank[nownum - 1];            if (i - 3 >= 0)            {                leftnum = stack[i - 3].num;                if (nowsuit == stack[i - 3].suit[leftnum - 1] || nowrank == stack[i - 3].rank[leftnum - 1])                {                    sflag = flag = 1;                    Cover(3, i, nowrank, nowsuit, leftnum);                }            }            if (i - 1 >= 0 && sflag == 0)   //如果之前没移动到前三个牌组并且前面有牌组            {                leftnum = stack[i - 1].num;                if (nowsuit == stack[i - 1].suit[leftnum - 1] || nowrank == stack[i - 1].rank[leftnum - 1])                {                    flag = 1;                    Cover(1, i, nowrank, nowsuit, leftnum);                }            }            if(flag == 1 && stack[i].num == 0)            {                Move(i);    //牌组向前移一位.                count--;    //牌组数量减一.                stack[count].num = 0;            } if (flag == 1)break;        }        if (flag == 0)            return count;    }}void Cover(int step,int i, char nowrank, char nowsuit, int leftnum){    stack[i - step].rank[leftnum] = nowrank;    stack[i - step].suit[leftnum] = nowsuit;    stack[i - step].num++;    stack[i].num--;}void Move(int i){    for (int j = i; j < 52; j++)    {        if (stack[j + 1].num == 0)        break;        for (int k = 0; k < stack[j + 1].num; k++)        {            stack[j].rank[k] = stack[j + 1].rank[k];            stack[j].suit[k] = stack[j + 1].suit[k];        }        stack[j].num = stack[j + 1].num;    }}



0 0