蓝桥杯 历届试题 剪格子(dfs搜索) - Freecode# - 博客园
int num[15][15],visit[15][15]; int i,j,n,m,sum,end=0; void Cutaws(int x,int y,int value,int count) { value+=num[x][y]; if(value==sum/2&&end!=1) { printf("%d\n",count+1); memset(visit,1,sizeof(visit)); end=1; return; } if(value>sum) return; if(y+1<n&&visit[x][y+1]==0) { visit[x][y+1]=1; Cutaws(x,y+1,value,count+1); visit[x][y+1]=0; } if(y-1>=0&&visit[x][y-1]==0) { visit[x][y-1]=1; Cutaws(x,y-1,value,count+1); visit[x][y-1]=0; } if(x+1<m&&visit[x+1][y]==0) { visit[x+1][y]=1; Cutaws(x+1,y,value,count+1); visit[x+1][y]=0; } if(y-1>=0&&visit[x-1][y]==0) { visit[x-1][y]=1; Cutaws(x,y,value,count+1); visit[x-1][y]=0; } } int main() { sum=0; memset(num,0,sizeof(num)); memset(visit,0,sizeof(visit)); scanf("%d%d",&n,&m); for(i=0;i<m;i++) for(j=0;j<n;j++) { scanf("%d",&num[i][j]); sum+=num[i][j]; } visit[0][0]=1; Cutaws(0,0,0,0); return 0; }
Read full article from 蓝桥杯 历届试题 剪格子(dfs搜索) - Freecode# - 博客园
如下图所示,3 x 3 的格子中填写了一些整数。
我们沿着图中的星号线剪开,得到两个部分,每个部分的数字和都是60。
本题的要求就是请你编程判定:对给定的m x n 的格子中的整数,是否可以分割为两个部分,使得这两个区域的数字和相等。
如果存在多种解答,请输出包含左上角格子的那个区域包含的格子的最小数目。
如果无法分割,则输出 0。
本题的要求就是请你编程判定:对给定的m x n 的格子中的整数,是否可以分割为两个部分,使得这两个区域的数字和相等。
如果存在多种解答,请输出包含左上角格子的那个区域包含的格子的最小数目。
如果无法分割,则输出 0。
输入格式
程序先读入两个整数 m n 用空格分割 (m,n<10)。
表示表格的宽度和高度。
接下来是n行,每行m个正整数,用空格分开。每个整数不大于10000。
表示表格的宽度和高度。
接下来是n行,每行m个正整数,用空格分开。每个整数不大于10000。
输出格式
输出一个整数,表示在所有解中,包含左上角的分割区可能包含的最小的格子数目。
样例输入1
3 3
10 1 52
20 30 1
1 2 3
10 1 52
20 30 1
1 2 3
样例输出1
3
样例输入2
4 3
1 1 1 1
1 30 80 2
1 1 1 100
1 1 1 1
1 30 80 2
1 1 1 100
样例输出2
10
dfs搜索题。
按深度优先搜索的思路从左上角开始搜索,累加当前数字,直到数字和为所有数字和的一半,返回走到当前的步数。
需要注意的是,输入行数和列数的时候注意输入顺序。我之前做过的这种类型的题,都是先输入行数再输入列数,而这道题却是先输入列数再输入行数。这着实坑到我了,调了好久才找到原因。
http://www.zhuangjingyang.com/%E5%89%AA%E6%A0%BC%E5%AD%90.htmlpublic class Main { private static int m = 0; //col private static int n = 0; //row private static int half = 0; private static int sum = 0; private static int minValue = 100; private static int count = 0; private static int select = 0; private static int tnum; private static int [][] num = new int[10][10]; private static int [][] flag = new int[10][10]; private static int xzb[] = {-1,1,0,0};//上下左右 private static int yzb[] = {0,0,-1,1}; public static void main(String[] args) { int i,j,maxNum = 0, all =0; Scanner cin = new Scanner(System.in); m = cin.nextInt(); n = cin.nextInt(); for(i=0;i<n; ++i) for(j=0;j<m;j++) { num[i][j] = cin.nextInt(); all += num[i][j]; //all为总和 if(num[i][j] > maxNum) //找出最大值 maxNum = num[i][j]; } if(all%2!=0 || maxNum > all/2) //如果为奇数或者最大值大于总和一半,则没有结果 System.out.println("0"); else { half = all /2 ; //将格子每个点都作为起点搜索一遍,两个 for 循环 for(i=0;i<m;i++) { for(j=0;j<n;j++) { select = 0; dfs(num[i][j],i,j); } } if(minValue != 100) //结果 System.out.print(minValue); else System.out.print("0"); } } static int isok(int x,int y) //判断传入的坐标值是否能被选入 { int yes = 0; //不越界并且不超出和一半 if((x>=n || x<0) || (y>=m||y<0)||(flag[x][y] == 1)||(sum+num[x][y] > half)) yes = 1; // 冲突 return yes; } static void back(int value,int x,int y)//执行回退处理 { if(x==0 && y==0) //如果将 num[0][0] 回退掉,则标记为未选入 select = 0; -- count ; sum -= value; flag[x][y] = 0; } static void dfs(int value,int x,int y) //dfs搜索 { int i, t1, t2; if(x==0 && y==0) //主要用于B点开始的搜素,判断num[0][0]有没有被选入 select = 1; flag[x][y] = 1; //标记为走过 ++count; sum += value; if( sum == half) { if(select == 1) /*如果num[0,0]被选入,主要用于非[0,0]点开始的搜索*/ tnum = count; else tnum = n*m - count; if(minValue > tnum) minValue = tnum; } else { for(i=0;i<4;i++)/*按 上下左右 顺序遍历*/ { t1 = x + xzb[i];/*引入t1,t2目的是使传入的x,y值不变,便于下面的回退*/ t2 = y + yzb[i]; if(isok(t1,t2) == 1) //判断是否可走 continue; dfs(num[t1][t2],t1,t2); } } //如果都不可以走,则回退 back(value,x,y); } }http://blog.csdn.net/acmman/article/details/18659573
int num[15][15],visit[15][15]; int i,j,n,m,sum,end=0; void Cutaws(int x,int y,int value,int count) { value+=num[x][y]; if(value==sum/2&&end!=1) { printf("%d\n",count+1); memset(visit,1,sizeof(visit)); end=1; return; } if(value>sum) return; if(y+1<n&&visit[x][y+1]==0) { visit[x][y+1]=1; Cutaws(x,y+1,value,count+1); visit[x][y+1]=0; } if(y-1>=0&&visit[x][y-1]==0) { visit[x][y-1]=1; Cutaws(x,y-1,value,count+1); visit[x][y-1]=0; } if(x+1<m&&visit[x+1][y]==0) { visit[x+1][y]=1; Cutaws(x+1,y,value,count+1); visit[x+1][y]=0; } if(y-1>=0&&visit[x-1][y]==0) { visit[x-1][y]=1; Cutaws(x,y,value,count+1); visit[x-1][y]=0; } } int main() { sum=0; memset(num,0,sizeof(num)); memset(visit,0,sizeof(visit)); scanf("%d%d",&n,&m); for(i=0;i<m;i++) for(j=0;j<n;j++) { scanf("%d",&num[i][j]); sum+=num[i][j]; } visit[0][0]=1; Cutaws(0,0,0,0); return 0; }
Read full article from 蓝桥杯 历届试题 剪格子(dfs搜索) - Freecode# - 博客园