zoukankan      html  css  js  c++  java
  • 从例题看数据结构队列和栈

    今天是周一,周末周六大了两天绿盟杯,被各种大佬暴虐,于是身为菜鸡的我就决定闭关,好了话不多说,今天记录下我看数据结构时的思考和转载的啊哈算法书一些知识。

            首先,开篇是这样描述的:星期天小哼和小哈约在一起玩桌游,他们正在玩一个非常古怪的扑克游戏——“小猫钓
      鱼”。游戏的规则是这样的:将一副扑克牌平均分成两份,每人拿一份。小哼先拿出手中的
      第一张扑克牌放在桌上,然后小哈也拿出手中的第一张扑克牌,并放在小哼刚打出的扑克牌
      的上面,就像这样两人交替出牌。出牌时,如果某人打出的牌与桌上某张牌的牌面相同,即
    可将两张相同的牌及其中间所夹的牌全部取走,并依次放到自己手中牌的末尾。当任意一人 手中的牌全部出完时,游戏结束,对手获胜。 假如游戏开始时,小哼手中有 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("小哼胜利
    ");
        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胜利
    ");
            printf("小a的牌:
    ");
            for(i=p1.head;i<=p1.tail-1;i++)
               printf("%d ",p1.data[i]);
               printf("
    ");
            if(s.top>0)
             {
                  printf("桌上的牌是:
    ");
                  for(i=1;i<=s.top;i++)
                      printf("%d ",s.data[i]);
                      printf("
    ");
             }
             else
                printf("桌上没牌了
    ");
        }
        else
        {
            printf("小b胜利
    ");
            printf("小b哼的牌:
    ");
            for(i=p2.head;i<=p2.tail-1;i++)
               printf("%d ",p2.data[i]);
               printf("
    ");
            if(s.top>0)
             {
                  printf("桌上的牌是:
    ");
                  for(i=1;i<=s.top;i++)
                      printf("%d ",s.data[i]);
                  printf("
    ");
             }
             else
                printf("桌上没牌了
    ");
        }
    return 0;
    }

    最后在我调试这段代码时报错pai[a] CXX0030: Error: expression cannot be evaluated,审计了半天,发现我在拷贝重复代码时间出错p2.data[p1.tail]=s.data[s.top];忘了更改。

  • 相关阅读:
    在路上。。。
    DNN模块打包(DNN-ModulePack简称为DNNMP)
    创建一个PortalSettings,这也行。
    对Web 2.0 的体验
    太空旅客 第七位 了
    计划今年每月至少写一篇技术性文章
    检索 COM 类工厂中 CLSID 为 {0002450000000000C000000000000046} 的组件时失败,原因是出现 以下错误: 80070005
    RadGrid RaisePostBackEvent 刷新页面问题。
    做为团队中的一员
    dnn captcha 图片 显示不了 见鬼了
  • 原文地址:https://www.cnblogs.com/kk328/p/9068986.html
Copyright © 2011-2022 走看看