c语言五子棋代码,

c语言五子棋代码,,第1张

package day17gobang;

import javautilArrays;

public class GoBangGame {

public static final char BLANK='';

public static final char BLACK='@';

public static final char WHITE='O';

public static final int MAX = 16;

private static final int COUNT = 5;

//棋盘

private char[][] board;

public GoBangGame() {

}

//开始游戏

public void start() {

board = new char[MAX][MAX];

//把二维数组都填充‘’

for(char[] ary: board){

Arraysfill(ary, BLANK);

}

}

public char[][] getChessBoard(){

return board;

}

public void addBlack(int x, int y) throws ChessExistException{

//@

//char blank = '';

//Systemoutprintln( x +"," + y + ":" + board[y][x] + "," + BLANK);

if(board[y][x] == BLANK){// x, y 位置上必须是空的才可以添棋子

board[y][x] = BLACK;

return;

}

throw new ChessExistException("已经有棋子了!");

}

public void addWhite(int x, int y)

throws ChessExistException{

if(board[y][x] == BLANK){// x, y 位置上必须是空的才可以添棋子

board[y][x] = WHITE;

return;

}

throw new ChessExistException("已经有棋子了!");

}

//chess 棋子:'@'/'O'

public boolean winOnY(char chess, int x, int y){

//先找到y方向第一个不是 blank的棋子

int top = y;

while(true){

if(y==0 || board[y-1][x]!=chess){

//如果y已经是棋盘的边缘, 或者的前一个不是chess

//就不再继续查找了

break;

}

y--;

top = y;

}

//向回统计所有chess的个数,如果是COUNT个就赢了

int count = 0;

y = top;

while(true){

if(y==MAX || board[y][x]!=chess){

//如果找到头 或者 下一个子不是chess 就不再继续统计了

break;

}

count++;

y++;

}

return count==COUNT;

}

//chess 棋子:'@'/'O'

public boolean winOnX(char chess, int x, int y){

//先找到x方向第一个不是 blank的棋子

int top = x;

while(true){

if(x==0 || board[y][x-1]!=chess){

//如果x已经是棋盘的边缘, 或者的前一个不是chess

//就不再继续查找了

break;

}

x--;

top = x;

}

//向回统计所有chess的个数,如果是COUNT个就赢了

int count = 0;

x = top;

while(true){

if(x==MAX || board[y][x]!=chess){

//如果找到头 或者 下一个子不是chess 就不再继续统计了

break;

}

count++;

x++;

}

return count==COUNT;

}

//chess 棋子:'@'/'O'

public boolean winOnXY(char chess, int x, int y){

//先找MAX向第一个不是 blank的棋子

int top = y;

int left = x;

while(true){

if(x==0 || y==0 || board[y-1][x-1]!=chess){

//如果x已经是棋盘的边缘, 或者的前一个不是chess

//就不再继续查找了

break;

}

x--;

y--;

top = y;

left=x;

}

//向回统计所有chess的个数,如果是COUNT个就赢了

int count = 0;

x = left;

y = top;

while(true){

if(x==MAX || y==MAX || board[y][x]!=chess){

//如果找到头 或者 下一个子不是chess 就不再继续统计了

break;

}

count++;

x++;

y++;

}

return count==COUNT;

}

//chess 棋子:'@'/'O'

public boolean winOnYX(char chess, int x, int y){

//先找到x方向第一个不是 blank的棋子

int top = y;

int left = x;

while(true){

if(x==MAX-1 || y==0 || board[y-1][x+1]!=chess){

//如果x已经是棋盘的边缘, 或者的前一个不是chess

//就不再继续查找了

break;

}

x++;

y--;

top = y;

left=x;

}

//向回统计所有chess的个数,如果是COUNT个就赢了

int count = 0;

x = left;

y = top;

while(true){

if(x==0 || y==MAX || board[y][x]!=chess){

//如果找到头 或者 下一个子不是chess 就不再继续统计了

break;

}

count++;

x--;

y++;

}

return count==COUNT;

}

public boolean whiteIsWin(int x, int y) {

//在任何一个方向上赢了,都算赢

return winOnY(WHITE, x, y) ||

winOnX(WHITE, x, y) ||

winOnXY(WHITE, x, y) ||

winOnYX(WHITE, x, y);

}

public boolean blackIsWin(int x, int y) {

return winOnY(BLACK, x, y) ||

winOnX(BLACK, x, y) ||

winOnXY(BLACK, x, y) ||

winOnYX(BLACK, x, y);

}

}

#include <iostream>

#include <cstdio>

#include <cstdlib>

#define MAXSIZE 50000

using namespace std;

//村子树节点,数据域有入栈出栈时间域、村子编号域

//树采用孩子兄弟链存储结构

typedef struct Village

{

    int num;        //村子编号

    int intime;     //深度优先遍历入栈时间

    int outtime;    //节点出栈时间

    struct Village firstchild;

    struct Village nextcousin;

}VillageNode;

typedef struct

{

    int top;

    VillageNode villages[MAXSIZE];

}Stack;

Stack s = (Stack )malloc(sizeof(Stack));

int time=0;     //记录栈访问时间

int addNode(VillageNode root, int a, int b);

VillageNode dfsfind(VillageNode root, int va, int vb);

void popStack(VillageNode p);

void pushStack(VillageNode p);

void dfs(VillageNode root);

void ifwait(int va, int vb, int vc);

//将p节点压入栈

void pushStack(VillageNode p)

{

    if(s->top>-1)

        printf("当前栈顶元素为%d,",s->villages[s->top]->num);

    else

        printf("当前栈元素为空,");

    s->villages[++s->top] = p;

    time++;     //栈访问次数加1

    p->intime = time;    //记录入栈时间

    printf("入栈后元素总数为%d,入栈元素为%d,intime: %d\n",s->top+1, p->num, time);

}

//将栈顶元素弹出,并将地址保存至p指针

void popStack(VillageNode p)

{

    if(s->top > -1)

    {

        p = s->villages[s->top];

        s->top--;

        time++;         //栈访问次数加1

        p->outtime = time;

        printf("出栈元素为%d, outtime: %d,出栈后元素总数为%d,",p->num, time, s->top+1);

    }

    if(s->top > -1)

        printf("当前栈顶元素为%d\n",s->villages[s->top]->num);

    else

        printf("当前栈元素为空\n");

}

VillageNode dfsfind(VillageNode root, int va)

{

    if(root == NULL)    //当当前节点为空时返回NULL

        return NULL;

    int v = root->num;

    VillageNode p, q;

    //curcnt++;           //用于记录当前访问过的节点数

    if(va == v )        //如果找到原先既有的节点,则返回该节点的指针

        return root;

    q = dfsfind(root->firstchild, va);  //递归访问孩子节点

    if(q != NULL)

        return q;

    //依次递归访问兄弟节点

    p = root->nextcousin;

    while(p != NULL)

    {

        q = dfsfind(p, va);

        if(q != NULL)

            return q;

        p = p->nextcousin;

    }

    return NULL;

    ///当访问过的节点达到总数仍没有找到va 或 vb节点时,返回NULL

    if(root->firstchild == NULL && root->nextcousin == NULL)

        return NULL;

    else

    {

        if(root->firstchild == NULL)

        {

            p = root->nextcousin;

            while(p != NULL)

            {

                dfsfind(p);

                p = p->nextcousin;

            }

        }

        else if(root->nextcousin == NULL)

        {

            dfsfind(root->firstchild);

        }

        else

        {

        }

    }/

}

//a必须是树中已经存在的节点

int addNode(VillageNode root, int va, int vb)

{

    VillageNode vp = dfsfind(root, va);   //寻找编号为a的村子

    VillageNode p, q;

    if(vp != NULL)

    {

        if(vp->num == va)     //找到村子a,遍历其孩子节点

        {

            p = vp->firstchild;

            q = vp;

            if(p == NULL)   //当vp节点下没有孩子节点时

            {

                VillageNode vn = (VillageNode) malloc(sizeof(VillageNode));

                vn->firstchild = NULL;

                vn->nextcousin = NULL;

                vn->num = vb;

                q->firstchild = vn;

                return 1;

            }

            while(p != NULL)

            {

                if(p->num == vb)     //当村子a存在到村子b的路时返回0

                    return 0;

                q = p;              //记录下当前节点

                p = p->nextcousin;  //p指向下一个节点

            }

            VillageNode vn = (VillageNode) malloc(sizeof(VillageNode));

            vn->firstchild = NULL;

            vn->nextcousin = NULL;

            vn->num = vb;

            q->nextcousin = vn;

            return 1;

        }

    }

    return -1;

}

void dfs(VillageNode root)

{

    pushStack(root);

    VillageNode p;

    p = root->firstchild;  //指向第一个孩子

    while(p != NULL)    //当孩子节点不为空时,递归访问孩子节点

    {

        dfs(p);

        p = p->nextcousin;

    }

    popStack(p);    //弹出栈顶元素

    return;

}

void ifwait(VillageNode root, int va, int vb, int vc)

{

    VillageNode VA = dfsfind(root,va);

    VillageNode VB = dfsfind(root,vb);

    VillageNode VC = dfsfind(root,vc);

    printf("找到的a,b,c分别为:%d %d %d\n",VA->num, VB->num, VC->num);

    if((VC->intime < VA->intime && VC->outtime > VA->outtime)       //当VC节点的入出栈时间区间包含VA的区间

       &&(VC->intime < VB->intime && VC->outtime > VB->outtime))    //且VC节点的入出栈时间区间包含VB的区间

    {

        //当VC是VA和VB的公共祖先时判断是否是最低公共祖先

        int a[2][MAXSIZE];  //二维数组第一行存放intime 第二行存放outtime 每一列对应一个节点 从左到右

        int m,n;

        m = VA->intime < VB->intime  VA->intime : VB->intime;  //记录VA、VB入栈的最小时间

        n = VA->outtime > VB->outtime  VA->outtime : VB->outtime;  //记录VA、VB出栈最大时间

        VillageNode p = VC->firstchild;

        int i=0;

        while(p != NULL)    //遍历VC节点所有的孩子节点 将孩子们的入出栈时间存入数组,方便二分查找

        {

            a[0][i] = p->intime;

            a[1][i] = p->outtime;

            i++;

            p = p->nextcousin;

        }

        //二分查找[m,n]区间是否包含在其中一个孩子节点中

        int low=0, high = i-1, mid;

        while(low <= high)

        {

            mid = (low + high) / 2;

            if(a[0][mid] <= m && a[1][mid] >= n)  //查找到有区间包含[m,n]区间时,说明VC不是VA和VB的最低公共祖先,则跳出循环

            {

                printf("No\n");

                return;

            }

            if(a[0][mid] > m)   //继续在a[0][lowmid-1]中查找

                high = mid - 1;

            else                //继续在a[0][mid+1high]中查找

                low = mid + 1;

        }

        printf("Yes\n");    //当查找结束仍没有找到该区间,说明VC是VA。VB的最低公共祖先

    }

    else if((VC->intime < VA->intime && VC->outtime > VA->outtime)  //当VC节点的入出栈时间区间包含VA的区间

        || (VC->intime < VB->intime && VC->outtime > VB->outtime))  //或VC节点的入出栈时间区间包含VB的区间

    {

        //此时VC是VA、VB其中一个节点的祖先,存在A-C-B的路径

        printf("Yes\n");

    }

    else        //当VC不是VA或VB节点的祖先时不存在A-C-B的路径

        printf("No\n");

    return;

}

int main()

{

    int N, M, a, b, c;

    printf("请输入小村个数:\n");

    scanf("%d",&N);

    VillageNode root = (VillageNode )malloc(sizeof(VillageNode));     //开辟指向深度优先搜索树的指针并建立深度优先搜素树

    root->firstchild = NULL;

    root->nextcousin = NULL;

    root->num = 0;

    //cnt++;

    printf("接下来,请依次输入包含一条双向道路的两个端点小村的编号:\n");

    while(--N)

    {

        scanf("%d %d", &a, &b); //读取边信息

        int flag = addNode(root, a, b);

        if(flag==0)

        {

            printf("小村%d到小村%d的路径已存在,无需再次输入,本次输入将不会被记录。\n", a, b);

            N++;

        }

        else if(flag == 1)

            printf("成功录入!%d-%d\n", a, b);

        else

            printf("录入失败!%d-%d\n", a, b);

    }

    s->top = -1;

    dfs(root);  //深度优先遍历一遍树

    printf("请输入测试样例个数:\n");

    scanf("%d", &M);

    printf("请依次输入测试样例:\n");

    while(M--)

    {

        scanf("%d %d %d", &a, &b, &c);

        ifwait(root, a, b, c);

    }

    return 0;

}

  #include <iostream>

  #include <cstdio>

  #include <cstdlib>

  #define MAXSIZE 50000

  using namespace std;

  //村子树节点,数据域有入栈出栈时间域、村子编号域

  //树采用孩子兄弟链存储结构

  typedef struct Village

  {

  int num; //村子编号

  int intime; //深度优先遍历入栈时间

  int outtime; //节点出栈时间

  struct Village firstchild;

  struct Village nextcousin;

  }VillageNode;

  typedef struct

  {

  int top;

  VillageNode villages[MAXSIZE];

  }Stack;

  Stack s = (Stack )malloc(sizeof(Stack));

  int time=0; //记录栈访问时间

  int addNode(VillageNode root, int a, int b);

  VillageNode dfsfind(VillageNode root, int va, int vb);

  void popStack(VillageNode p);

  void pushStack(VillageNode p);

  void dfs(VillageNode root);

  void ifwait(int va, int vb, int vc);

  //将p节点压入栈

  void pushStack(VillageNode p)

  {

  if(s->top>-1)

  printf("当前栈顶元素为%d,",s->villages[s->top]->num);

  else

  printf("当前栈元素为空,");

  s->villages[++s->top] = p;

  time++; //栈访问次数加1

  p->intime = time; //记录入栈时间

  printf("入栈后元素总数为%d,入栈元素为%d,intime: %d\n",s->top+1, p->num, time);

  }

  //将栈顶元素弹出,并将地址保存至p指针

  void popStack(VillageNode p)

  {

  if(s->top > -1)

  {

  p = s->villages[s->top];

  s->top--;

  time++; //栈访问次数加1

  p->outtime = time;

  printf("出栈元素为%d, outtime: %d,出栈后元素总数为%d,",p->num, time, s->top+1);

  }

  if(s->top > -1)

  printf("当前栈顶元素为%d\n",s->villages[s->top]->num);

  else

  printf("当前栈元素为空\n");

  }

  VillageNode dfsfind(VillageNode root, int va)

  {

  if(root == NULL) //当当前节点为空时返回NULL

  return NULL;

  int v = root->num;

  VillageNode p, q;

  //curcnt++; //用于记录当前访问过的节点数

  if(va == v ) //如果找到原先既有的节点,则返回该节点的指针

  return root;

  q = dfsfind(root->firstchild, va); //递归访问孩子节点

  if(q != NULL)

  return q;

  //依次递归访问兄弟节点

  p = root->nextcousin;

  while(p != NULL)

  {

  q = dfsfind(p, va);

  if(q != NULL)

  return q;

  p = p->nextcousin;

  }

  return NULL;

  ///当访问过的节点达到总数仍没有找到va 或 vb节点时,返回NULL

  if(root->firstchild == NULL && root->nextcousin == NULL)

  return NULL;

  else

  {

  if(root->firstchild == NULL)

  {

  p = root->nextcousin;

  while(p != NULL)

  {

  dfsfind(p);

  p = p->nextcousin;

  }

  }

  else if(root->nextcousin == NULL)

  {

  dfsfind(root->firstchild);

  }

  else

  {

  }

  }/

  }

  //a必须是树中已经存在的节点

  int addNode(VillageNode root, int va, int vb)

  {

  VillageNode vp = dfsfind(root, va); //寻找编号为a的村子

  VillageNode p, q;

  if(vp != NULL)

  {

  if(vp->num == va) //找到村子a,遍历其孩子节点

  {

  p = vp->firstchild;

  q = vp;

  if(p == NULL) //当vp节点下没有孩子节点时

  {

  VillageNode vn = (VillageNode) malloc(sizeof(VillageNode));

  vn->firstchild = NULL;

  vn->nextcousin = NULL;

  vn->num = vb;

  q->firstchild = vn;

  return 1;

  }

  while(p != NULL)

  {

  if(p->num == vb) //当村子a存在到村子b的路时返回0

  return 0;

  q = p; //记录下当前节点

  p = p->nextcousin; //p指向下一个节点

  }

  VillageNode vn = (VillageNode) malloc(sizeof(VillageNode));

  vn->firstchild = NULL;

  vn->nextcousin = NULL;

  vn->num = vb;

  q->nextcousin = vn;

  return 1;

  }

  }

  return -1;

  }

  void dfs(VillageNode root)

  {

  pushStack(root);

  VillageNode p;

  p = root->firstchild; //指向第一个孩子

  while(p != NULL) //当孩子节点不为空时,递归访问孩子节点

  {

  dfs(p);

  p = p->nextcousin;

  }

  popStack(p); //弹出栈顶元素

  return;

  }

  void ifwait(VillageNode root, int va, int vb, int vc)

  {

  VillageNode VA = dfsfind(root,va);

  VillageNode VB = dfsfind(root,vb);

  VillageNode VC = dfsfind(root,vc);

  printf("找到的a,b,c分别为:%d %d %d\n",VA->num, VB->num, VC->num);

  if((VC->intime < VA->intime && VC->outtime > VA->outtime) //当VC节点的入出栈时间区间包含VA的区间

  &&(VC->intime < VB->intime && VC->outtime > VB->outtime)) //且VC节点的入出栈时间区间包含VB的区间

  {

  //当VC是VA和VB的公共祖先时判断是否是最低公共祖先

  int a[2][MAXSIZE]; //二维数组第一行存放intime 第二行存放outtime 每一列对应一个节点 从左到右

  int m,n;

  m = VA->intime < VB->intime VA->intime : VB->intime; //记录VA、VB入栈的最小时间

  n = VA->outtime > VB->outtime VA->outtime : VB->outtime; //记录VA、VB出栈最大时间

  VillageNode p = VC->firstchild;

  int i=0;

  while(p != NULL) //遍历VC节点所有的孩子节点 将孩子们的入出栈时间存入数组,方便二分查找

  {

  a[0][i] = p->intime;

  a[1][i] = p->outtime;

  i++;

  p = p->nextcousin;

  }

  //二分查找[m,n]区间是否包含在其中一个孩子节点中

  int low=0, high = i-1, mid;

  while(low <= high)

  {

  mid = (low + high) / 2;

  if(a[0][mid] <= m && a[1][mid] >= n) //查找到有区间包含[m,n]区间时,说明VC不是VA和VB的最低公共祖先,则跳出循环

  {

  printf("No\n");

  return;

  }

  if(a[0][mid] > m) //继续在a[0][lowmid-1]中查找

  high = mid - 1;

  else //继续在a[0][mid+1high]中查找

  low = mid + 1;

  }

  printf("Yes\n"); //当查找结束仍没有找到该区间,说明VC是VA。VB的最低公共祖先

  }

  else if((VC->intime < VA->intime && VC->outtime > VA->outtime) //当VC节点的入出栈时间区间包含VA的区间

  || (VC->intime < VB->intime && VC->outtime > VB->outtime)) //或VC节点的入出栈时间区间包含VB的区间

  {

  //此时VC是VA、VB其中一个节点的祖先,存在A-C-B的路径

  printf("Yes\n");

  }

  else //当VC不是VA或VB节点的祖先时不存在A-C-B的路径

  printf("No\n");

  return;

  }

  int main()

  {

  int N, M, a, b, c;

  printf("请输入小村个数:\n");

  scanf("%d",&N);

  VillageNode root = (VillageNode )malloc(sizeof(VillageNode)); //开辟指向深度优先搜索树的指针并建立深度优先搜素树

  root->firstchild = NULL;

  root->nextcousin = NULL;

  root->num = 0;

  //cnt++;

  printf("接下来,请依次输入包含一条双向道路的两个端点小村的编号:\n");

  while(--N)

  {

  scanf("%d %d", &a, &b); //读取边信息

  int flag = addNode(root, a, b);

  if(flag==0)

  {

  printf("小村%d到小村%d的路径已存在,无需再次输入,本次输入将不会被记录。\n", a, b);

  N++;

  }

  else if(flag == 1)

  printf("成功录入!%d-%d\n", a, b);

  else

  printf("录入失败!%d-%d\n", a, b);

  }

  s->top = -1;

  dfs(root); //深度优先遍历一遍树

  printf("请输入测试样例个数:\n");

  scanf("%d", &M);

  printf("请依次输入测试样例:\n");

  while(M--)

  {

  scanf("%d %d %d", &a, &b, &c);

  ifwait(root, a, b, c);

  }

  return 0;

  }

  

这个我也看晕了,编号和下标混着挺难理解的。我自己写了一个:

#include <stdioh>

#include <stdlibh>

int main()

{

int i,count,remain,total[25][2];

//total为二维数组,第二维的第一个地址存人的编号,第二个存这个人当前的状态。

for(i=0;i<25;i++)

{

total[i][0]=i; //数组中下标为i的人的编号。

total[i][1]=0; //数组总下标为i的人的状态:已经出列就置1,否则置0

}

i=0; //初始编号为0

count=0; //已经数的人数,count==3时此人就出列

remain=25; //最后剩下的人数

while(remain>0) //所有人循环数直到全部出列 (如果最后要剩下两人条件就改成remain>2)

{

if(total[i%25][1]==0) //如果当前的人状态为0,表示没出列,所以要数,如果为1,表示已经出列了,就不对他计数了。i%25是为了循环,比如数到25的话就变成了编号为0的人,i 一直往前数就能保证在25人中循环计数。

{

count++;

}

if(count==3) //如果数到3,这个人就要出列了

{

total[i%25][1]=1; //此人状态变成1,即出列

remain--; //剩余的人数减一

count=0; //重新从0开始计数

printf("%d ",total[i%25][0]); //输出这个人的编号

}

i++; // i 增1 保持循环计数。

}

return 0;

}

这个解析很清楚了,先理解SCANF和二维数组的原理

scanf将输入值复制到后面第二个参数所指向的位置,也就是说第二个参数是一个指针

用其名字来引用二维数组即x[0][0]到X[2][1]表示的是六个指针,指向数组存储范围的指针

而如果不写第二个括号比如X[0]就是默认指向第一个元素即X[0][0]

那么很容易就得出答案,scanf输入的是一个%d 就是一个INT数值,那么只能填充一行中的一位

而未被填充的哪一位就还是初始的0

欢迎分享,转载请注明来源:表白网

原文地址:https://h5.hunlipic.com/biaobai/2905319.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2024-01-20
下一篇2024-01-20

发表评论

登录后才能评论

评论列表(0条)

    保存