栈和队列——小猫钓鱼

​ 星期天A和B在一起玩扑克牌,他们在玩一个古怪的扑克牌游戏——小猫钓鱼。游戏的规则是这样的,将一副扑克牌平均分成两份,每人拿一份。A先拿出手中的第一章牌放在桌上,然后B也从手里拿出一张牌放在桌上,就放在A刚刚出牌的上面,就像这样两个人交替出牌。出牌时,如果某人打出的牌与桌面上某张牌的牌面相同,即可将两张相同的牌和其中夹的牌全部取走,并依次放到自己的牌的末尾。当一个人的牌耗尽时,游戏结束,对手获胜。

​ 假如游戏开始时,A手中有6张牌,顺序为2 4 1 2 5 6,B手中也有6张牌,顺序为3 1 3 5 6 4,最终谁会获胜呢。

​ 先分析一下这游戏有几种操作,A有两种操作,分别是出牌和赢牌。这恰好对应队列的两个操作,出牌就是出队,赢牌就是入队。B的操作也是一样的。而桌子就像是一个栈,每打一张牌到桌子上就相当于入栈,有人赢牌时就相当于出栈。根据之前的规则,我们需要两个队列,一个栈来模拟游戏。

​ 首先创建一个结构体来模拟实现队列:

struct queue
{
    int data[1000];
    int head;
    int tail;
};

​ 上面代码中head用来存储队头,tail用来存储队尾。数组data用来存储队列中的元素,数组data的大小预设为1000,其实应该设置的更大一些,以防数组越界。

​ 再创建一个结构体来实现栈:

struct stack
{
    int data[10];
    int top;
};

​ 其中top用来存储栈顶,数组data用来存储栈中的元素,大小设置为10,因为牌面数字就只有0~9不同的牌面,所以桌面上最多有9张牌,因此数组的大小设置为10就够了。

​ 接下来需要定义两个队列变量q1和q2。用来模拟A和B手里的牌。定义一个栈变量来模拟桌上的牌。

struct queue q1, q2;
struct stack s;

​ 接下来来初始化一下队列和栈;

// 队列和栈都初始化为空,因为一开始手上和桌上都没有牌
q1.head = 0;
q1.tail = 0;

q2.head = 0;
q2.tail = 0;

s.top = 0;

​ 接下来需要读入A和B手中的初始的牌,分两次读入,每次读入6个数,分别插入q1和q2中。

for (i = 0; i < 6; i++) {
    scanf("%d", &q1.data[q1.tail++]);
}

for (i = 0; i < 6; i++) {
    scanf("%d", &q2.data[q2.tail++]);
}

​ 现在准备工作已经完毕,游戏正式开始,A先出牌

t = q1.data[q1.head];

​ A打出一张牌后,先把这个牌存到临时变量里,然后去判断A是否能够赢回桌上的牌。也就是判断桌面上有没有和A打出的牌相同的牌。

flage = 0;
for (i = 1; i <= s.top; i++) {
    if (t == s.data[i]) {
        flag = 1;
        break;
    }
}

​ 如果flag为1就表示A可以赢走桌上的牌,需要将赢得的牌依次放入A的手中

if (flage == 1) {
    q1.head++;
    q1.data[q1.tail] = t;
    q1.tail++;
    
    while (s.data[s.top] != t) {
        q1.data[q1.tail] = s.data[s.top];
        q1.tail++;
        s.top--;
    }
}
A出牌的所有阶段模拟结束了,B和A出牌是一样的。接下来就判断游戏怎么结束。即两个人中有一个人的牌用完了就游戏结束了。因此需要在模拟两个人出牌的代码外面加一个while循环来判断:
while(q1.head < q1.tail && q2.head < q2.tail) // q1和q2都不为空的时候执行出牌循环

​ 最后一步,输出谁最后赢了游戏,以及游戏结束后获胜者手上的牌和桌上的牌。如果A获胜了,B手上就没有牌了,即q2.head == q2.tail,队列为空。

if (q2.head == q2.tail) {
    printf("A WIN\n");
    printf("A 手中的牌是:");
    for (i = q1.head; i < q1.tail; i++) {
        printf(" %d", q1.data[i]);
    }
    
    if (s.top > 0) {
        printf("桌上的牌是:");
        for (i = 0; i <= s.top; i++){
             printf(" %d", s.data[i]);
        }
    } else {
        printf("桌上已经没有牌了");
    }
}

​ 反之B获胜,现在代码已经实现的差不多了。

​ 当然,代码还有很多的可以优化的地方,完整代码如下:

#include 

struct queue
{
    int data[1000];
    int head;
    int tail;
};

struct stack
{
    int data[10];
    int top;
};

int main()
{
    struct queue q1, q2;
	struct stack s;
    int book[10];
    int i, t;
    
    q1.head = 0;
	q1.tail = 0;

	q2.head = 0;
	q2.tail = 0;

	s.top = 0;
    
    for (i = 1; i <= 9; i++) {
        book[i] = 0;
    }
    
    for (i = 0; i < 6; i++) {
    	scanf("%d", &q1.data[q1.tail++]);
	}

	for (i = 0; i < 6; i++) {
    	scanf("%d", &q2.data[q2.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[i] = i;
        } else {
            q1.head++;
            q1.data[q1.tail] = t;
            q1.tail++;
            
            while (s.data[s.top] != t) {
                book[s.data[s.top]] = 0;
                q1.data[q.tail] = s.data[s.top];
                s.top--;
            }
            
            book[s.data[s.top]] = 0;
            q1.data[q1.tail] = s.data[s.top];
            q1.tail++;
            s.top--;
        }
        
        t = q2.data[q2.head];
        
        if (book[t] == 0) {
            q2.head++;
            s.top++;
            s.data[s.top] = t;
            book[i] = i;
        } else {
            q2.head++;
            q2.data[q2.tail] = t;
            q2.tail++;
            
            while (s.data[s.top] != t) {
                book[s.data[s.top]] = 0;
                q2.data[q.tail] = s.data[s.top];
                s.top--;
            }
            
            book[s.data[s.top]] = 0;
            q2.data[q2.tail] = s.data[s.top];
            q2.tail++;
            s.top--;
        }
    }
    
    if (q2.head == q2.tail) {
    	printf("A WIN\n");
    	printf("A 手中的牌是:");
    	for (i = q1.head; i < q1.tail; i++) {
        	printf(" %d", q1.data[i]);
    	}
    
    	if (s.top > 0) {
        	printf("桌上的牌是:");
        	for (i = 0; i <= s.top; i++){
            	printf(" %d", s.data[i]);
        	}
    	} else {
        	printf("桌上已经没有牌了");
    	}
	} else {
        printf("B WIN\n");
    	printf("B 手中的牌是:");
    	for (i = q2.head; i < q2.tail; i++) {
        	printf(" %d", q2.data[i]);
    	}
    
    	if (s.top > 0) {
        	printf("桌上的牌是:");
        	for (i = 0; i <= s.top; i++){
            	printf(" %d", s.data[i]);
        	}
    	} else {
        	printf("桌上已经没有牌了");
    	}
    }
    
    return 0;
}

​ 输入参数

2 4 1 2 5 6
3 1 3 5 6 4

​ 验证模拟即可。

你可能感兴趣的:(算法,数据结构,数据结构,算法)