【算法】矩阵填数,深度优先搜索(DFS),Pascal改C语言

面向对象的上机实验

题目

以下列方式向 5*5 矩阵中填入数字。设数字i(1=<i<=25),则数字i+1 的坐标位置应为(E, W)。(E, W)可根据下列关系由(x,y)算出:

1)(E, W)=(x±3,y)

2)(E, W)=(x,y±3)

3)(E, W)=(x±2,y±2)

求解问题如下:

编写一个程序,当数字1被指定于某个起始位置时,列举出其它24个数字应在的位置;列举该条件下的所有可能方案。

参考答案

网上搜索到数学奥赛中本题的Pascal代码

来自http://blog.sina.com.cn/s/blog_1317189490102vp1k.html

 1 Program lx9_1_3;
 2 uses crt;
 3 const n=5;
 4       d:array[1..8,1..2] of shortint=((3,0),(-3,0),(0,3),(0,-3),
 5                                       (2,2),(2,-2),(-2,2),(-2,-2));
 6 var x0,y0:byte;
 7     a:array[1..n,1..n] of byte;
 8     total:longint;
 9
10 procedure print;
11   var i,j:integer;
12   begin
13     inc(total);
14     gotoxy(1,3);
15     writeln(‘[‘,total,‘]‘);
16     for i:=1 to n do
17       begin
18         for j:=1 to n do
19           write(a[i,j]:3);
20         writeln;
21       end;
22   end;
23
24 procedure try(x,y,k:byte);
25   var i,x1,y1:integer;
26   begin
27     for i:=1 to 8 do
28       begin
29         x1:=x+d[i,1];y1:=y+d[i,2];
30         if (x1>0) and (y1>0) and (x1<=n)
31            and (y1<=n) and (a[x1,y1]=0) then
32              begin
33                a[x1,y1]:=k;
34                if k=n*n then print
35                   else try(x1,y1,k+1);
36                a[x1,y1]:=0;
37              end;
38       end;
39   end;
40
41 begin
42   clrscr;
43   write(‘x0,y0=‘);readln(x0,y0);
44   fillchar(a,sizeof(a),0);
45   total:=0;a[x0,y0]:=1;
46   try(x0,y0,2);
47   writeln(‘Total=‘,total);
48   writeln(‘Press any key to exit..。‘);
49   repeat until keypressed;
50 end.

自改C语言代码

运用了深度优先搜索算法。

可以输入一个起始位置的坐标后,列举出所有可能方案和方案个数。

也可以输出所有初始点方案的个数。

 1 #include <stdio.h>
 2 #define N 5//格子行列数
 3
 4 int next[8][2]={{3,0},{-3,0},{0,3},{0,-3},{2,2},{2,-2},{-2,2},{-2,-2}};//下一步变换的位移
 5 int x0,y0;//输入的初始坐标
 6 int matrix[N][N];//存储nxn矩阵中的数字
 7 int total;//方案数量
 8
 9 //打印一个矩阵的函数
10 void printMatrix(){
11     int i,j;
12     total+=1;//出来一次结果,就打印一次,方案数+1
13     printf("第%d种方案:\n",total);
14     for(i=0;i<N;i++){
15         for(j=0;j<N;j++){
16             printf("%4d",matrix[i][j]);//%4d表示输出宽度为4,且右对齐
17         }
18         printf("\n");
19     }
20     printf("\n");
21 }
22 ////每个初始点都输出方案的个数的话就不把每个方案打印出来了,太占地方
23 //void printMatrix(){
24 //    int i,j;
25 //    total+=1;//出来一次结果,就打印一次,方案+1
26 //}
27
28 //主要函数,(x,y)是矩阵内坐标,k是第几个数字
29 void try(x,y,k){
30     int i,x1,y1;//x1,y1是本次要找的坐标
31     //将8个位移都试一遍
32     for(i=0;i<8;i++){
33         x1=x+next[i][0];
34         y1=y+next[i][1];
35         //如果该位置不超过边界且没有数字,则方案可行,把数字装进这个位置
36         if((x1>-1)&&(y1>-1)&&(x1<N)&&(y1<N)&&(matrix[x1][y1]==0)){
37             matrix[x1][y1]=k;
38             //如果k=25即已经搜索完,可以打印了
39             if(k==N*N)
40                 printMatrix();
41             //如果还没到25,就继续搜索下一个位置
42             else
43                 try(x1,y1,k+1);
44             //本次打印完/本次搜索尝试到死路,回溯到上一节点去往另一分支前,将这一节点清零
45             matrix[x1][y1]=0;
46         }
47     }
48 }
49
50
51 int main()
52 {
53     //输入坐标
54     printf("请输入第一个数的坐标(逗号间隔):");
55     scanf("%d,%d",&x0,&y0);
56
57     //矩阵整体清0(第一条在dev-c++可以跑,vc++不行,还是用老办法)
58     //memset(matrix, 0, sizeof(matrix));
59     int i,j;
60     for(i=0;i<N;i++){
61         for(j=0;j<N;j++){
62             matrix[i][j]=0;
63         }
64     }
65
66     //数据初始化,运行
67     total=0;//方案数为零
68     x0-=1;y0-=1;//用户输入坐标从1开始,c语言数组从0开始
69     matrix[x0][y0]=1;//第一个位置赋值1
70     try(x0,y0,2); //从数字2开始放置
71
72     printf("总共有%d种摆放方案\n\n",total);
73
74
75 //    //每个初始点都输出方案的个数
76 //    int m,n;
77 //    for(m=0;m<5;m++){
78 //        for(n=0;n<5;n++){
79 //                x0=m;y0=n;
80 //                //矩阵整体清0
81 //                int i,j;
82 //                for(i=0;i<N;i++){
83 //                    for(j=0;j<N;j++){
84 //                        matrix[i][j]=0;
85 //                    }
86 //                }
87 //                total=0;//每次节点前方案数清零
88 //                matrix[x0][y0]=1;//第一个位置赋值1
89 //                try(x0,y0,2); //从数字2开始放置
90 //                printf("数字1被指定于(%d,%d)有%d种方案\n",m+1,n+1,total);
91 //        }
92 //        printf("\n");//每5行之后打个空行好看点
93 //    }
94 }

结果

  • 输入一个起始点坐标后输出的方案

  • 输出所有起始点的方案个数:

原文地址:https://www.cnblogs.com/threells1939/p/11735549.html

时间: 2024-10-07 20:28:42

【算法】矩阵填数,深度优先搜索(DFS),Pascal改C语言的相关文章

【算法入门】深度优先搜索(DFS)

深度优先搜索(DFS) [算法入门] 1.前言深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍历的算法.它的思想是从一个顶点V0开始,沿着一条路一直走到底,如果发现不能到达目标解,那就返回到上一个节点,然后从另一条路开始走到底,这种尽量往深处走的概念即是深度优先的概念. 你可以跳过第二节先看第三节,:) 2.深度优先搜索VS广度优先搜索 2.1演示深度优先搜索的过程还是引用上篇文章的样例图,起点仍然是V0,我们修改一下题目意思,只需要让你找出一条V0到V6的道路,而无需最短

深度优先搜索(DFS)详解

深度优先搜索(DFS) [算法入门] 1.前言 深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍历的算法.它的思想是从一个顶点V0开始,沿着一条路一直走到底,如果发现不能到达目标解,那就返回到上一个节点,然后从另一条路开始走到底,这种尽量往深处走的概念即是深度优先的概念. 你可以跳过第二节先看第三节,:) 2.深度优先搜索VS广度优先搜索 2.1演示深度优先搜索的过程 还是引用上篇文章的样例图,起点仍然是V0,我们修改一下题目意思,只需要让你找出一条V0到V6的道路,而无需

[LeetCode OJ] Word Search 深度优先搜索DFS

Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be us

bzoj5010: [Fjoi2017]矩阵填数

Description 给定一个 h*w 的矩阵,矩阵的行编号从上到下依次为 1..h,列编号从左到右依次1..w.在这个矩阵中你需要在每 个格子中填入 1..m 中的某个数.给这个矩阵填数的时候有一些限制,给定 n 个该矩阵的子矩阵,以及该子矩阵的 最大值 v,要求你所填的方案满足该子矩阵的最大值为 v.现在,你的任务是求出有多少种填数的方案满足 n 个限 制.两种方案是不一样的当且仅当两个方案至少存在一个格子上有不同的数.由于答案可能很大,你只需要输出答 案 对 1,000,000,007

[BZOJ5010][FJOI2017]矩阵填数(状压DP)

5010: [Fjoi2017]矩阵填数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 90  Solved: 45[Submit][Status][Discuss] Description 给定一个 h*w 的矩阵,矩阵的行编号从上到下依次为 1..h,列编号从左到右依次1..w.在这个矩阵中你需要在每 个格子中填入 1..m 中的某个数.给这个矩阵填数的时候有一些限制,给定 n 个该矩阵的子矩阵,以及该子矩阵的 最大值 v,要求你所填的方案满

python实现基础的深度优先搜索(DFS, depth first search)解决数的全排列问题

数的全排列,是一个很简单的问题,平时我们用笔用纸就能列出答案,但是数列位多的时候,排列的结果就有非常多了,例如有1,2,3,4,5,6,7,8,9这一个数列,有9个数字,则有9!(9的阶乘)这么多种结果.那是非常大的.今天我就来介绍用深度优先搜索来解决这个数的全排列的问题. 深度优先搜索 首先简单介绍一下深度优先搜索,深度优先搜索的关键在于当下该如何做,至于下一步如何做,就与当下做的一样.深度优先搜索的基本模型为: dfs(step): 判断边界:执行相关操作,返回 尝试每一种可能 for( i

算法导论22.3深度优先搜索 练习总结 (转载)

22.3-1 画一个 3*3 的网格,行和列的抬头分别标记为白色.灰色和黑色,对于每个表单元 (i, j),请指出对有向图进行深度优先搜索的过程中,是否可能存在一条边,链接一个颜色为 i 的结点和一个颜色为 j 的结点.对于每种可能的边,指明该种边的类型.另外,请针对无向图的深度优先搜索再制作一张这样的网格. ANSWER:   22.3-2 给出深度优先搜索算法在图 22-6 上的运行过程.假定深度优先搜索算法的第 5~7 行的 for 循环是以字母表顺序依次处理每个结点,假定每条邻接链表皆以

深度优先搜索DFS (poj2386,poj1979, poj3009,poj1321,aoj0033,aoj0118)

深度优先搜索(DFS) 往往利用递归函数实现(隐式地使用栈). 深度优先从最开始的状态出发,遍历所有可以到达的状态.由此可以对所有的状态进行操作,或列举出所有的状态. 1.poj2386 Lake Couting 题意:八连通被认为连接在一起,求总共有多少个水洼? Sample Input: 10 12 W........WW. .WWW.....WWW ....WW...WW. .........WW. .........W.. ..W......W.. .W.W.....WW. W.W.W.

深度优先搜索 DFS(Depath First Search, DFS)

深度优先搜索是一种枚举所有完整路径以遍历所有情况的搜索方法.(不撞南墙不回头) DFS一般用递归来实现,其伪代码思路过程一般如下: void DFS(必要的参数){    if (符和遍历到一条完整路径的尾部){        更新某个全局变量的值    }    if (跳出循环的临界条件){        return;    }    对所有可能出现的情况进行递归} 常见题型1: 代码实现: 1 #include <stdio.h> 2 const int maxn = 30; 3 in