今天是周一,周末周六大了两天绿盟杯,被各种大佬暴虐,于是身为菜鸡的我就决定闭关,好了话不多说,今天记录下我看数据结构时的思考和转载的啊哈算法书一些知识。
首先,开篇是这样描述的:星期天小哼和小哈约在一起玩桌游,他们正在玩一个非常古怪的扑克游戏——“小猫钓
鱼”。游戏的规则是这样的:将一副扑克牌平均分成两份,每人拿一份。小哼先拿出手中的
第一张扑克牌放在桌上,然后小哈也拿出手中的第一张扑克牌,并放在小哼刚打出的扑克牌
的上面,就像这样两人交替出牌。出牌时,如果某人打出的牌与桌上某张牌的牌面相同,即
可将两张相同的牌及其中间所夹的牌全部取走,并依次放到自己手中牌的末尾。当任意一人 手中的牌全部出完时,游戏结束,对手获胜。 假如游戏开始时,小哼手中有 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