#include<stdio.h>
struct queue{
int data[10001];
int head;
int tail;
};
struct stack{
int top;
int data[10001];
};
int main(){
struct queue q1,q2;
struct stack stk1;
int i,j = 1;
q1.head = 1;
q1.tail = 1;
q2.head = 1;
q2.tail = 1;
stk1.top = 1;
for(i = 1;i <= 6;i ++){ //每一块之前先检查
scanf("%d",&q1.data[q1.tail]);
q1.tail ++;
}
printf("start 1:");
for(i = q1.head;i < q1.tail;i ++){
printf("%d",q1.data[i]);
}
printf("\n");
for(i = 1;i <= 6;i ++){
scanf("%d",&q2.data[q2.tail]);
q2.tail ++;
}
printf("start 2:");
for(i = q2.head;i < q2.tail;i ++){
printf("%d",q2.data[i]);
}
printf("\n");
printf("stack:");
for(i = 1;i <= stk1.top;i ++){
printf("%d",stk1.data[i]);
}
printf("\n");
while(1){
int rem = stk1.top;
for(;stk1.top > 0;stk1.top --){
if(q1.data[q1.head] == stk1.data[stk1.top]){
for(;stk1.top <= rem;stk1.top ++){
if(stk1.data[stk1.top] != 0){
q1.data[q1.tail] = stk1.data[stk1.top];
stk1.data[stk1.top] = 0;
q1.tail ++;
}
}
break;
}
}
if(stk1.top == 0 && j == 1){
stk1.top = 1;
stk1.data[stk1.top] = q1.data[q1.head];
q1.head ++;
j ++;
}
else if(stk1.top == 0){
stk1.top = rem + 1;
stk1.data[stk1.top] = q1.data[q1.head];
q1.head ++;
}
else{
q1.data[q1.tail] = q1.data[q1.head];
q1.tail++;
q1.head++;
}
/*if(stk1.data[--stk1.top] != 0){
stk1.data[stk1.top] = q1.data[q1.head];
}
else{
q1.data[q1.tail++] = q1.data[q1.head ++];
}*/
printf("1:");
for(i = q1.head;i < q1.tail;i ++){
printf("%d",q1.data[i]);
}
printf("\n");
printf("stack1:");
for(i = 1;i <= stk1.top;i ++){
printf("%d",stk1.data[i]);
}
printf("\n");
if(q1.head == q1.tail){
printf("小哈赢了!\n");
printf("手牌:");
for(i = q2.head;i < q2.tail;i ++){
printf("%d ",q2.data[i]);
}
break;
}
rem = stk1.top;
for(;stk1.top > 0;stk1.top --){
if(q2.data[q2.head] == stk1.data[stk1.top]){
for(;stk1.top <= rem;stk1.top ++){
if(stk1.data[stk1.top] != 0){
q2.data[q2.tail++] = stk1.data[stk1.top];
stk1.data[stk1.top] = 0;
}
}
break;
}
}
if(stk1.top == 0){
stk1.top = rem + 1;
stk1.data[stk1.top] = q2.data[q2.head];
q2.head ++;
}
else{
q2.data[q2.tail] = q2.data[q2.head];
q2.head ++;
q2.tail ++;
}
printf("2:");
for(i = q2.head;i < q2.tail;i ++){
printf("%d",q2.data[i]);
}
printf("\n");
printf("stack2:");
for(i = 1;i <= stk1.top;i ++){
printf("%d",stk1.data[i]);
}
printf("\n");
if(q2.head == q2.tail){
printf("小哼赢了!\n");
printf("手牌:");
for(i = q1.head;i < q1.tail;i ++){
printf("%d ",q1.data[i]);
}
break;
}
}
}
这是倒着收牌的代码(检查了,应该是对的)
输入简单的数据1 2 3 4 5 6 后结果是正确的
1 2 3 4 5 6
#include<stdio.h>
struct queue{
int data[1001]; //数组data用来存储队列中的元素
int head; //head用来存储队头
int tail; //tail用来存储队尾
};
struct stack{
int data[11]; //数组data用来存储栈中的元素
int top; //top用来存储栈顶
};
int main()
{
struct queue q1,q2; //q1用来模拟小哼手中的牌,q2用来模拟小哈手中的牌
struct stack s; //栈变量s用来模拟桌上的牌
int book[10];
int i,t;
/*初始化队列q1和q2为空,因为此时两人手中都还没有牌*/
q1.head=1;q1.tail=1;
q2.head=1;q2.tail=1;
s.top=0; //初始化栈s为空,因为最开始的时候桌上也没有牌
for(i=0;i<=10;i++)
s.data[i]=0;
for(i=0;i<=9;i++)
book[i]=0;
for(i=1;i<=6;i++){ //先读入6张牌,放到小哼手上
scanf("%d",&q1.data[q1.tail]); //读入一个数到队尾
q1.tail++; //队尾往后挪一位
}
for(i=1;i<=6;i++){ //再读入6张牌,放到小哈手上
scanf("%d",&q2.data[q2.tail]);
q2.tail++;
}
printf("stack start:");
for(i = 1;i <= s.top;i ++){
printf("%d",s.data[i]);
}
printf("\n");
printf("q1.tail = %d\n",q1.tail);
while(q1.head<q1.tail && q2.head<q2.tail){ //当队列不为空的时候执行循环
t=q1.data[q1.head]; //小哼先亮出一张牌
if(book[t]==0)
{
q1.head++; //小哼已经打出一张牌,所以要把打出的牌出队
s.top++;
s.data[s.top]=t; //再把打出的牌放到桌上,即入栈
book[t]=1;
}
else
{
q1.head ++;
int rem = s.top;
while(s.data[s.top]!=t)
{
s.top--;
}
for(i = s.top;i <= rem;i ++){
printf("i = %d\n",i);
book[s.data[i]]=0;
q1.data[q1.tail]=s.data[i];
//s.data[i] = 0;
q1.tail++;
printf("q1.tail = %d\n",q1.tail);
}
printf("before t given in 1:");
for(i = q1.head;i < q1.tail;i ++){
printf("%d",q1.data[i]);
}
printf("\n");
printf("t = %d\n",t);
q1.data[q1.tail] = t;
printf("after t given in 1:");
for(i = q1.head;i < q1.tail;i ++){
printf("%d",q1.data[i]);
}
printf("\n");
s.top --;
q1.tail ++;
}
//printf("book1:%d , s.data[1]:%d\n",book[2],s.data[1]);
printf("1:");
for(i = q1.head;i < q1.tail;i ++){
printf("%d",q1.data[i]);
}
printf("\n");
printf("stack1:");
for(i = 1;i <= s.top;i ++){
printf("%d",s.data[i]);
}
printf("\n");
if(q1.head==q1.tail) break;
t=q2.data[q2.head];
if(book[t]==0)
{
q2.head++;
s.top++;
s.data[s.top]=t;
book[t]=1;
}
else
{
q2.head ++;
int rem = s.top;
while(s.data[s.top]!=t)
{
s.top--;
}
//printf("before for book2:%d , s.data[1]:%d\n",book[2],s.data[1]);
for(i = s.top;i <= rem;i ++){
//printf("i = %d\n",i);
//printf("before = 0 in for book2:%d , s.data[1]:%d\n",book[2],s.data[1]);
book[s.data[i]]=0;
//printf("in for book2:%d , s.data[1]:%d\n",book[2],s.data[1]);
q2.data[q2.tail]=s.data[i];
//s.data[i] = 0;
q2.tail++;
}
q2.data[q2.tail] = t;
s.top --;
q2.tail ++;
}
//printf("book2:%d , s.data[1]:%d\n",book[2],s.data[1]);
printf("2:");
for(i = q2.head;i < q2.tail;i ++){
printf("%d",q2.data[i]);
}
printf("\n");
printf("stack2:");
for(i = 1;i <= s.top;i ++){
printf("%d",s.data[i]);
}
printf("\n");
if(q2.head==q2.tail) break;
}
if(q2.head==q2.tail)//如果小哼获胜那么小哈手中一定没有牌了(队列q2为空)
{
printf("小哼win\n");
printf("小哼当前手中的牌是");
for(i=q1.head;i<=q1.tail-1;i++)
printf(" %d",q1.data[i]);
if(s.top>0) //如果桌上有牌则依次输出桌上的牌
{
printf("\n桌上的牌是");
for(i=1;i<=s.top;i++)
printf(" %d",s.data[i]);
}
else
printf("\n桌上已经没有牌了");
}
else
{
printf("小哈win\n");
printf("小哈当前手中的牌是");
for(i=q2.head;i<=q2.tail-1;i++)
printf(" %d",q2.data[i]);
if(s.top>0)
{
printf("\n桌上的牌是");
for(i=1;i<=s.top;i++)
printf(" %d",s.data[i]);
}
else
printf("\n桌上已经没有牌了");
}
return 0;
}
我拿正确答案改写了一遍,只是交换了桌面上有相同牌时牌回收的顺序
还修改了
int data[11];
防止定格
错误(好像还有个q2.head搞成了q1.head)
book[s.data[i]]=0;
这里之前错写为book[i]=0;花了我好大的精力,用printf打印才找出来的
出现了很大的数,后来才发现时越界了。我忽略了我的队列和栈是有限的,所以最后都是错的,只不过是错的,所以我把队列的数调到了
data[1001]
发现在出错前两个代码的结果都是一样的,这验证了最开始的代码
这是正确的代码(1 1 1 1 1 1 1 1 1 1 1 1这样的例子当然会死循环 ),但是刚写出来的时候却有十分多的错误。实在找不出之后(一个个数字去代)我使用了printf打印局部结果的方法去找出了BUG
q1.head = 1;
q1.tail = 2;
q2.head = 1;
q2.tail = 2;
stk1.top = 1;
for(i = 1;i <= 6;i ++){ //每一块之前先检查
scanf("%d",&q1.data[i]);
q1.tail ++;
}
for(i = 1;i <= 6;i ++){
scanf("%d",&q2.data[i]);
q2.tail ++;
}
我的本意就是tail放在head的后面先,再在给q1.data[head]赋值的过程中tail,然后我用i来了个等效替代,毕竟head走不开,但是我忽略了第一次head在的位置就是没有的,赋值进去的时候,这个时候tail更不需要走。后面的才要。这样的错误后面还有。
if(stk1.top == 0){
stk1.top = rem + 1;
}
if(stk1.data[--stk1.top] != 0){
stk1.data[++stk1.top] = q1.data[q1.head++];
}
else{
q1.data[q1.tail++] = q1.data[q1.head ++];
}
也是忽略了第一次的空栈是要先录入的,stk1.top不需要移动。
for(;stk1.top <= rem;stk1.top ++){
if(stk1.data[stk1.top] != 0){
q2.data[q2.tail++] = stk1.data[stk1.top];
stk1.data[stk1.top] = 0;
}
}
这里的if本来也是不存在的,因为我不记得(?)我这样搞的栈里面有的地方是0来着
else{
q1.data[q1.tail++] = q1.data[q1.head ++];
}
我想别的情况去了结果把这个情况——把回收的牌给放回自己牌堆的情况
else{
q2.data[q2.head] = q2.data[q2.tail];
q2.head ++;
q2.tail ++;
}
搞错赋值
q2.data[q2.tail] = q2.data[q2.head];
才对
小问题”结果花了我许多时间——写完代码脑子太累了,根本不可能有时间去追击这些问题。平时就要做好积累,明白可能的易错点。
还有脑子累了没时间去回忆易错点是因为学栈和队列的时候不熟悉,思考这两个知识点的时候已经花费大量时间了。能在基础阶段练好易错点的纠正这是最好的。
同时还要加强printf打印错误局部结果的方法的运用,不要很久才想起来有这个方法。
还是要多做题,不要以为简单就不去做了