今天是周一,周末周六大了两天绿盟杯,被各种大佬暴虐,于是身为菜鸡的我就决定闭关,好了话不多说,今天记录下我看数据结构时的思考和转载的啊哈算法书一些知识。
首先,开篇是这样描述的:星期天小哼和小哈约在一起玩桌游,他们正在玩一个非常古怪的扑克游戏——“小猫钓
鱼”。游戏的规则是这样的:将一副扑克牌平均分成两份,每人拿一份。小哼先拿出手中的
第一张扑克牌放在桌上,然后小哈也拿出手中的第一张扑克牌,并放在小哼刚打出的扑克牌
的上面,就像这样两人交替出牌。出牌时,如果某人打出的牌与桌上某张牌的牌面相同,即
可将两张相同的牌及其中间所夹的牌全部取走,并依次放到自己手中牌的末尾。当任意一人 手中的牌全部出完时,游戏结束,对手获胜。 假如游戏开始时,小哼手中有 6张牌,顺序为 2 4 1 2 5 6,小哈手中也有 6张牌,顺序 为 3 1 3 5 6 4,终谁会获胜呢?现在你可以拿出纸牌来试一试。接下来请你写一个程序来 自动判断谁将获胜。这里我们做一个约定,小哼和小哈手中牌的牌面只有 1~9。
在这道题目中,我们首先考虑的事扑克牌的存放的问题,这可以用数组完成,接下来我们考虑桌面牌的存放,也是可以用数组表示,但是数组长度怎么设置呢,开小了,会导致越界问题;开大了,又会导致浪费;由于牌又有9张不同的,我们考虑设置成10,好吧这些貌似有点low,我们直接进一步分析,首先设置队列如下:
struct duilie{ int data[1000]; int head; int tail; };
接下来设置栈来存储桌上的牌,由于只有九张不同的牌面,我们设置数组长度为10
struct stack{ int data[10]; //九张牌面 int top; };
下面就是队列和栈的初始化
struct duilie p1; struct duilie p2; //设置两个变量来存储两人的牌 struct stack s; p1.head=1; p1.tail=1; p2.head=1; p2.tail=1; //队列的初始化 s.top=0; //栈的初始化
我们接下来进行读取牌,每次读入一张牌,然后储存到队列中
for(i=1;i<=6;i++) { scanf("%d",&p1.data[p1.tail]); p1.tail++; //读取到队列后,队尾递增 } for(i=1;i<=6;i++) { scanf("%d",&p2.data[p2.tail]); p2.tail++; }
然后是出牌处理
a=p1.data[p1.head] //第一个人首先出牌 //打出的牌我们首先放到桌面上,与桌子上的牌进行比较 flag=0 for(i=1;i<=top;i++) { if(a==s[i]){flag=1;break;} } //flag=0表明桌面上没有出的牌,牌需要留在桌面 if(flag==0) { p1.head++; //出牌,队列下标增加 s.top++; s.data[s.top]=a; //没有相同牌,进行入栈,即放在桌子上 } //flag=1说明有牌,可以赢牌 if(flag==1) { p1.head++; //出牌,队列下标增加 p1.data[p1.tail]=a; p1.tail++; //赢牌,把刚才的牌放到队尾 while(s.data[s.top]!=a) { p1.data[p1.tail]=s.data[s.top]; p1.tail++; s.top--; //把桌面可以赢得牌依次放到栈尾 } }
接下来,我们就是判断胜利的过程了;
while(p1.head<p1.tail&&p2.head<p2.tail) //当队列非空进行循环 if(p2.head==p2.tail) { printf("小哼胜利\n"); printf("小哼的牌:"); for(i=p1.head;i<=p1.tail;i++) printf("%d",p1.data[i]); if(s.top>0) { printf("桌上的牌是:"); for(i=1;i<=s.top;i++) printf("%d",s.data[i]); } else printf("桌上没牌了"); }
上面是就是这个程序的分析了,由于第二个人获胜的代码相同与第一个人,我这里直接省略了部分代码;下面贴出完整代码
#include<stdio.h> struct duilie { int data[1000]; int head; int tail; }; struct stack { int data[10]; //九张牌面 int top; }; int main() { struct duilie p1,p2; struct stack s; int pai[10]; int i,a; p1.head=1; p1.tail=1; p2.head=1; p2.tail=1; //队列的初始化 s.top=0; //栈的初始化 for(i=1;i<=9;i++) pai[i]=0; //标记在桌上的牌 for(i=1;i<=6;i++) { scanf("%d",&p1.data[p1.tail]); p1.tail++; //读取到队列后,队尾递增 } for(i=1;i<=6;i++) { scanf("%d",&p2.data[p2.tail]); p2.tail++; } while(p1.head<p1.tail && p2.head<p2.tail) { a=p1.data[p1.head] ; //第一个人首先出牌 //打出的牌我们首先放到桌面上,与桌子上的牌进行比较 if(pai[a]==0) { p1.head++; //出牌,队列下标增加 s.top++; s.data[s.top]=a; //没有相同牌,进行入栈,即放在桌子上 pai[a]=1; } //flag=1说明有牌,可以赢牌 else { p1.head++; //出牌,队列下标增加 p1.data[p1.tail]=a; p1.tail++; //赢牌,把刚才的牌放到队尾 while(s.data[s.top]!=a) { pai[s.data[s.top]]=0; p1.data[p1.tail]=s.data[s.top]; p1.tail++; s.top--; //把桌面可以赢得牌依次放到栈尾 } } a=p2.data[p2.head] ; //第一个人出牌 //打出的牌我们首先放到桌面上,与桌子上的牌进行比较 if(pai[a]==0) { p2.head++; //出牌,队列下标增加 s.top++; s.data[s.top]=a; //没有相同牌,进行入栈,即放在桌子上 pai[a]=1; } else { p2.head++; //出牌,队列下标增加 p2.data[p2.tail]=a; p2.tail++; //赢牌,把刚才的牌放到队尾 while(s.data[s.top]!=a) { pai[s.data[s.top]]=0; p2.data[p2.tail]=s.data[s.top]; p2.tail++; s.top--; //把桌面可以赢得牌依次放到栈尾 } } } if(p2.head==p2.tail) { printf("小a胜利\n"); printf("小a的牌:\n"); for(i=p1.head;i<=p1.tail-1;i++) printf("%d ",p1.data[i]); printf("\n"); if(s.top>0) { printf("桌上的牌是:\n"); for(i=1;i<=s.top;i++) printf("%d ",s.data[i]); printf("\n"); } else printf("桌上没牌了\n"); } else { printf("小b胜利\n"); printf("小b哼的牌:\n"); for(i=p2.head;i<=p2.tail-1;i++) printf("%d ",p2.data[i]); printf("\n"); if(s.top>0) { printf("桌上的牌是:\n"); for(i=1;i<=s.top;i++) printf("%d ",s.data[i]); printf("\n"); } else printf("桌上没牌了\n"); } return 0; }
最后在我调试这段代码时报错pai[a] CXX0030: Error: expression cannot be evaluated,审计了半天,发现我在拷贝重复代码时间出错p2.data[p1.tail]=s.data[s.top];忘了更改。
来源:https://www.cnblogs.com/kk328/p/9068986.html