zoukankan      html  css  js  c++  java
  • 【胡搞的不能AC的题解,暴力搜索一发博弈问题】1995 三子棋 51Nod

    题目来源: syu校赛
    基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题
    原题链接: https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1995

    小的时候大家一定玩过“井”字棋吧。也就是在九宫格中,只要任意行、列,或者任意连续对角线上面出现三个相同的,就能获胜。现在小明和小花也在玩三子棋,但是他们不是在九宫格里,而是在3×4的格子里面。现在小明先下,但是他知道小花这个人很聪明,他想知道第一步下在哪一个地方最合适,你能帮帮他吗?



    Input
    第一行输入一个整数T,表示数据组数(1<T<10000); 
    第二行输入两个整数x,y,表示3×4格子里面的一个坐标(x,y)(1<=x<=3,1<=y<=4);
    Output
    每组数据输出最后小明输赢的结果,如果小明一定能赢,第一行输出“Win”,第二行输出小明所需要花的最少步数;如果小明跟小花只能打成平手,第一行输出“Equal”,第二行输出数字0;如果小明不能赢也不能跟小花打成平手,第一行输出“Lose”,第二行输出小花赢小明所需要花的最少步数。
    Input示例
    2
    2 1
    2 4
    Output示例
    Equal
    0
    Equal
    0


    -------------------------------------------------------------------------------
    看到这个题目我想到了搜索,但计算了一下时间复杂度:不是很大,应该不会超时!但是,这是个博弈问题,暴力穷举的话没法进行模拟!

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<iostream>
      4 #include<stdlib.h>
      5 #include<math.h>
      6 #include<algorithm>
      7 #include<queue>
      8 using namespace std;
      9 #define inf 0x3f3f3f3f
     10 #define emin 1e-10
     11 #define ll long long   //10:19--
     12 int mp[4][5],flag;
     13 int dir[8][2]= { {0,1},{0,-1},{1,0},{1,-1},{1,1},{-1,-1},{-1,0},{-1,1} };
     14 
     15 int check()
     16 {
     17     int i,j;
     18     for(j=1; j<=4; j++) //竖行
     19     {
     20         if(mp[1][j]==mp[2][j]&&mp[2][j]==mp[3][j]&&mp[3][j]!=-1)
     21             return mp[1][j];
     22     }
     23     for(i=1; i<=3; i++) //横行
     24     {
     25         if(mp[i][1]==mp[i][2]&&mp[i][2]==mp[i][3]&&mp[i][3]!=-1)
     26             return mp[i][2];
     27         if(mp[i][2]==mp[i][3]&&mp[i][3]==mp[i][4]&&mp[i][3]!=-1)
     28             return mp[i][2];
     29     }
     30     if(mp[1][1]==mp[2][2]&&mp[2][2]==mp[3][3]&&mp[3][3]!=-1)
     31         return mp[1][1];
     32     if(mp[1][2]==mp[2][3]&&mp[2][3]==mp[3][4]&&mp[3][4]!=-1)
     33         return mp[1][2];
     34     if(mp[1][3]==mp[2][2]&&mp[2][2]==mp[3][1]&&mp[3][1]!=-1)
     35         return mp[1][3];
     36     if(mp[1][4]==mp[2][3]&&mp[2][3]==mp[3][2]&&mp[3][2]!=-1)
     37         return mp[2][3];
     38     return -1; //当前局面无结果
     39 }
     40 void print_mp()
     41 {
     42     for(int i=1; i<=3; i++)
     43     {
     44         for(int j=1; j<=4; j++)
     45             printf("%3d",mp[i][j]);
     46         printf("\n");
     47     }
     48 }
     49             //num=0表示先手下棋者,num=1表示后手下棋者
     50 int game(int step,int num) //当前正要走的的步数step,num表示当前step步下棋者
     51 {
     52     int i,j,k;
     53     if(step==13) //至多12个格子
     54         return -1;
     55     if(k=check(),k!=-1) //不用下棋时就已经达到获胜或者失败的局面了!
     56     {
     57         return k;
     58     }
     59     for(i=1; i<=3; i++)
     60     {
     61         for(j=1; j<=4; j++)
     62         {
     63             if(mp[i][j]==-1)
     64             {
     65                 mp[i][j]=num;
     66 
     67                 if(check()==num) //下完一步后,检验整个棋盘可以获胜则返回
     68                 {
     69                     mp[i][j]=-1;
     70                     return num;  //返回当前局面的获胜者
     71                 }
     72                 if(game(step+1,!num)==num) //后续递归博弈处理可以胜利则返回
     73                 {
     74                     mp[i][j]=-1;
     75                     return num;  //返回当前局面的获胜者
     76                 }
     77                 mp[i][j]=-1;
     78             }
     79         }
     80     }
     81     return !num;
     82 }
     83 
     84 
     85 int main()
     86 {
     87     int a,b,ans;
     88     // init();
     89     for(a=1; a<=3; a++)
     90     {
     91         for(b=1; b<=4; b++)
     92         {
     93             memset(mp,-1,sizeof(mp));
     94             mp[a][b]=0;//先手先下一步
     95             ans=game(2,1);  //调用博弈函数
     96             if(ans==0)
     97                 printf("当a=%d,b=%d, 先手Win\n",a,b);
     98             else
     99                 printf("当a=%d,b=%d, 先手Lose 或者 Equal\n",a,b);
    100         }
    101     }
    102 
    103     return 0;
    104 }
    View Code

    友情提示这不是题解!没法判断是否可以达到平局的局面,但这题不存在平局的局面;想判断的话,可以用调用game函数的次数来判断!(可能吧!)

    像这类博弈问题基本都是找规律的,找不出来规律就没法了!除非很水的题!

    你不逼自己一把,你永远都不知道自己有多优秀!只有经历了一些事,你才会懂得好好珍惜眼前的时光!
  • 相关阅读:
    祝各位博友新年快乐,全家幸福,大展宏图,财源滚滚!
    Android中级第五讲GPRS定位的实现
    Android高级开发第二讲Android中API翻译之Activity
    Android 图标、音频、颜色RGB工具集
    Android初级开发第八讲之startActivityForResult方法讲解
    Android高级开发第三讲应用程序基础
    Android高级开发第四讲API之Service
    Android高级开发第五讲API之Content Providers
    物联网操作系统是否需要基于Java和虚拟机进行构筑
    Android高级开发第四讲API之Intents and Intent Filters
  • 原文地址:https://www.cnblogs.com/zhazhaacmer/p/8117808.html
Copyright © 2011-2022 走看看