码迷,mamicode.com
首页 > 其他好文 > 详细

8.4 智力趣题(2)

时间:2016-07-19 20:36:27      阅读:182      评论:0      收藏:0      [点我收藏+]

标签:

8-18 knight2.c

 1 #include <stdio.h>
 2 typedef struct coord
 3 {
 4    int x;
 5    int y;
 6 }Coordinate;    //棋盘上的坐标 
 7 int chessboard[8][8] = { 0 };    //初始化棋盘各单元格状态 
 8 int curstep;    //马跳的步骤序号 
 9 Coordinate move[8] = { {-2, 1}, {-1, 2}, {1, 2}, {2, 1},
10           {2, -1}, {1, -2}, {-1, -2}, {-2, -1}};    //马可走的八个方向
11 void display() //显示走法
12 {
13    int i, j;
14    for (i = 0; i < 8; i++)
15    {
16       for (j = 0; j < 8; j++)
17          printf("%4d", chessboard[i][j]);
18       printf("\n");
19    }
20    getch();
21 }
22 void travel(Coordinate curpos) //向前走一步
23 {
24    Coordinate next;
25    int i;
26    if (curpos.x < 0 || curpos.x > 7 || curpos.y < 0 || curpos.y > 7)    //越界 
27       return;
28    if (chessboard[curpos.x][curpos.y])    //若已走过 
29       return;    //是否遍历过
30    chessboard[curpos.x][curpos.y] = curstep;    //保存步数 
31    curstep++;
32    if (curstep > 64)    //64个棋盘位置都走完了 
33    {
34       display();
35       printf("\n");
36    } 
37    else
38    {
39       for (i = 0; i < 8; i++)    // 8个可能的方向
40       {
41          next.x = curpos.x + move[i].x;
42          next.y = curpos.y + move[i].y;
43          if (next.x < 0 || next.x > 7 || next.y < 0 || next.y > 7);
44          else
45              travel(next);
46       }
47    }
48    chessboard[curpos.x][curpos.y] = 0; //清除步数序号 
49    curstep--; //减少步数 
50 }
51 int main()
52 {
53    int i, j;
54    Coordinate start;
55    printf("输入马的起始位置:");
56    scanf("%d%d", &start.x, &start.y);
57    if (start.x < 1 || start.y < 1 || start.x > 8 || start.y > 8)    //越界 
58    {
59       printf("坐标输入错误,请重新输入!\n");
60       exit(0);
61    }
62    start.x--;
63    start.y--;
64    curstep = 1;    //第1步 
65    travel(start);
66    getch();
67    return 0;
68 }

8-19 knight3.c

  1 #include<stdio.h>
  2 #define STACK_INIT_SIZE 100
  3 #define STACKINCREMENT 10
  4 typedef struct
  5 {
  6    int x;
  7    int y;
  8 }Coordinate; //坐标位置 
  9 int chessboard[8][8] = { 0 };
 10 Coordinate move[8] ={ {-2, 1}, {-1, 2}, {1, 2}, {2, 1}, 
 11                     {2, -1}, {1, -2}, {-1, -2}, {-2, -1} };//马可走的八个方向
 12 
 13 typedef struct
 14 {
 15    int ord; //步数序号 
 16    Coordinate seat; //位置 
 17    int di; //方向 
 18 }SElemType; //栈操作的节点 
 19 typedef struct
 20 {
 21    SElemType *base;
 22    SElemType *top;
 23    int stacksize;
 24 }SqStack; //栈结构 
 25 int InitStack(SqStack * s1)
 26 {
 27    s1->base = (SElemType *) malloc(STACK_INIT_SIZE * sizeof(SElemType));
 28    if (!s1->base)
 29       exit(1);
 30    s1->top = s1->base;
 31    s1->stacksize = STACK_INIT_SIZE;
 32    return (1);
 33 }
 34 SElemType Pop(SqStack * s, SElemType e)
 35 {
 36    e = *(--s->top);
 37    return e;
 38 }
 39 int Push(SqStack * s1, SElemType e)
 40 {
 41    if (s1->top - s1->base >= s1->stacksize)
 42    {
 43       s1->base =
 44          (SElemType *) realloc(s1->base,
 45          (s1->stacksize + STACKINCREMENT) * sizeof(SElemType));
 46       if (!s1->base)
 47          exit(1);
 48       s1->top = s1->base + s1->stacksize;
 49       s1->stacksize += STACKINCREMENT;
 50    }
 51    *(s1->top++) = e;
 52    return 1;
 53 }
 54 int StackEmpty(SqStack * s)
 55 {
 56    if (s->base == s->top)
 57       return (1);
 58 
 59    else
 60       return (0);
 61 }
 62 
 63 int Pass(Coordinate s) //是否能通过 
 64 {
 65    if ((chessboard[s.x][s.y] == 0) && (s.x <= 7) && (s.x >= 0) && (s.y <= 7)
 66       && (s.y >= 0))
 67       return (1);
 68    else
 69       return (0);
 70 }
 71 Coordinate NextPos(Coordinate s, int i) //下一位置 
 72 {
 73    s.x = s.x + move[i].x;
 74    s.y = s.y + move[i].y;
 75    return (s);
 76 }
 77 void knight(Coordinate start)
 78 {
 79    int curstep = 0;
 80    SqStack S;
 81    SElemType e;
 82    Coordinate curpos = start; //当有位置 
 83    InitStack(&S); //初始化栈 
 84    do
 85    {
 86       if (Pass(curpos)) //若当前位置可走
 87       {
 88          curstep++;  //步数增加 
 89          chessboard[curpos.x][curpos.y] = curstep; //保存步数序号 
 90          e.seat = curpos; //保存当前位置 
 91          e.ord = curstep; //步数 
 92          e.di = 0; //方向 
 93          Push(&S, e); //入栈 
 94          if (curstep == 64) //若已走完64个单元格
 95          {       
 96             break; //退出循环
 97          }
 98          else
 99          {
100              curpos = NextPos(curpos, e.di); //取下一位置 
101          }
102       }
103       else //若当前位置不可走 
104       {
105          if (!StackEmpty(&S)) //若栈不为空 
106          {
107             Pop(&S, e); //将上一步出栈 
108             if (e.di == 7) //若8个位置都走过
109             { 
110                 chessboard[e.seat.x][e.seat.y] = 0; //取消该步的步数序号 
111             }
112             while (e.di == 7 && !StackEmpty(&S)) //当前8个位置已走完,且栈不为空 
113             {
114                e = Pop(&S, e); //出栈 
115                if (e.di == 7) //若8个位置都试探过了 
116                   chessboard[e.seat.x][e.seat.y] = 0; //取消该步的步数序号 
117                curstep = e.ord; //保存步数序号 
118             }
119             if (e.di < 7) //若还有位置未进行试探 
120             {
121                e.di++; //试探下一位置  
122                Push(&S, e); //入栈 
123                curpos = NextPos(e.seat, e.di); //取下一位置 
124             }
125          }
126       }
127    } while (!StackEmpty(&S)); //若栈中还有数据,继续循环 
128    if (StackEmpty(&S)) //若栈为空 
129    {
130       printf("遍历失败!\n");
131       printf("请按任意键推出本程序\n");
132       getch();
133       exit(1);
134    }
135 }
136 int main()
137 {
138    int i,j;
139    Coordinate start;
140    printf("输入马的起始位置坐标:");
141    scanf("%d %d", &start.x, &start.y);
142    if(start.x< 1  || start.y < 1 
143        || start.x > 8 || start.y > 8) //超界 
144    {
145        printf("坐标输入错误,请重新输入!\n");
146        exit(0);
147    }
148    start.x -= 1;
149    start.y -= 1;   
150    knight(start);
151    printf("马的路线:\n");
152    for (i = 0; i < 8; i++)
153    {
154       for (j = 0; j < 8; j++)
155          printf("%4d", chessboard[i][j]);
156        printf("\n");
157    }
158    getch();
159    return 0;
160 }

8-20 queens1.c

 1 #include <stdio.h >
 2 int iCount = 0;//记录解的序号的全局变量
 3 int Queens[8];//记录皇后在各列上的放置位置的全局数组
 4 void Output()//输出一个解,即一种没有冲突的放置方案
 5 {
 6    int i,j,flag=1;
 7    printf("第%2d种方案(★表示皇后):\n", ++iCount);//输出序号。 
 8    printf("  ");
 9    for(i=1;i<=8;i++)
10        printf("");
11    printf("\n");
12    for (i = 0; i < 8; i++)
13    {
14        printf("");
15        for (j = 0; j < 8; j++)
16        {
17            if(Queens[i]-1 == j)
18                printf("");
19            else
20            {
21                if (flag<0)
22                    printf("  ");
23                else
24                    printf("");               
25            }
26            flag=-1*flag;
27        }
28        printf("▏\n");
29        flag=-1*flag;
30    }
31    printf("  ");
32    for(i=1;i<=8;i++)
33        printf("");
34    printf("\n");  
35    getch();
36 }
37 int IsValid(int n)//断第n个皇后是否与前面皇后行成攻击
38 {
39    int i;
40    for (i = 0; i < n; i++)//第n个皇后与前面n-1个皇后比较 
41    {
42        if (Queens[i] == Queens[n])//两个皇后在同一行上,返回0。
43          return 0;
44        if (abs(Queens[i] - Queens[n]) == (n - i))//两个皇后在同一对角线上,返回0。
45          return 0;
46    }
47    return 1;//没有冲突,返回1。
48 }
49 void Queen(int n)//在第n列放置皇后
50 {
51    int i;
52    if (n == 8)//若8个皇后已放置完成
53    {
54       Output(); //输出 
55       return;
56    }
57    for (i = 1; i <= 8; i++)//在第n列的各个行上依次试探
58    { 
59       Queens[n] = i;//在该列的第i行上放置皇后。 
60       if (IsValid(n))//没有冲突,就开始下一列的试探
61          Queen(n + 1); //递归调用进行下一步 
62    }
63 }
64 int main()
65 { 
66    printf("八皇后排列方案:\n"); 
67    Queen(0);//从第0列开始递归试探 
68    getch();
69    return 0;
70 }

 

8.4 智力趣题(2)

标签:

原文地址:http://www.cnblogs.com/wozixiaoyao/p/5686051.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!