使用dir数组检查相邻方格

来源:互联网 发布:程序员 博客 平台 编辑:程序博客网 时间:2024/06/08 09:52

有些跟图相关的题目需要我们检查某一个方格与附近的方格的关系

最近看到两段类似的程序

一段来自于用DFS解方格填数:点击打开链接

另一段也是用DFS解剪邮票:点击打开链接

源码贴在下面:

方格填数:

#include <cstdio>#include <queue>#include <map>#include <cmath>#include <vector>#include <cstring>#include <iostream>#include <stack>#include <algorithm>using namespace std;const int r = 3, c = 4;int mapp[10][10];int numv[15];int cou;int dir[4][2] = { 0, -1, -1, -1, -1, 0, -1, 1 };bool check(int x, int y, int n) {for (int i = 0; i < 4; i++) {int nx = x + dir[i][0];int ny = y + dir[i][1];if (nx >= 0 && nx < r && ny >= 0 && ny < c) {//相邻的点有相邻的数字//还没有填过数字的格子-10 肯定不会等于当前格子0-9 +1或-1if (mapp[nx][ny] == n - 1 || mapp[nx][ny] == n + 1) {return false;}}}return true;}void dfs(int dep, int pos) {//(2,3)为缺口,结束if (dep == 2 && pos == 3) {cou++;#if 0for (int i = 0; i < r; i++) {for (int j = 0; j < c; j++) {printf("%4d", mapp[i][j]);}puts("");}puts("");system("pause");#endifreturn;}if (pos >= c) {dfs(dep + 1, 0);}else {for (int i = 0; i <= 9; i++) {//这个数i没用过,并且没有越出格子if (!numv[i] && check(dep, pos, i)) {numv[i] = true;mapp[dep][pos] = i;dfs(dep, pos + 1);mapp[dep][pos] = -10;numv[i] = false;}}}}int main(){//初始化为一个比较大的负数,那么在for (int i = 0; i <= 5; i++) {for (int j = 0; j <= 5; j++) {mapp[i][j] = -10;}}memset(numv, false, sizeof(numv));cou = 0;dfs(0, 1); //(0,0)为缺口,所以从(0,1)开始cout << cou << endl;  //1580return 0;}

注:这段代码中使用 #if 和 #endif 来查看中间结果的方法也非常精髓

剪邮票:

#include <stdio.h>  #include <string.h>  int mpt[3][4];  int mpt_visit[3][4];  int num[6];   int have[13];  int visit[13];  int ans = 0;  int Count = 0;  void init()  {      int k = 1;      for(int i = 0 ; i < 3 ; i ++)          for(int j = 0 ; j < 4 ; j ++)          {              mpt[i][j] = k;              k ++;          }  }  int dir[4][2] = {0,1,0,-1,-1,0,1,0};  //判断五个数是否能连在一起  void dfs_find(int x,int y)  {      for(int i = 0 ; i < 4 ; i++)      {          int tx,ty;          tx = x + dir[i][0];          ty = y + dir[i][1];          if(tx < 0 || tx >= 3 || ty < 0 || ty >= 4) continue;          if(have[mpt[tx][ty]] == 0 || mpt_visit[tx][ty])continue;          mpt_visit[tx][ty] = 1;          Count ++;          dfs_find(tx,ty);      }  }  void Solve()  {      int i;      memset(have,0,sizeof(have));      memset(mpt_visit,0,sizeof(mpt_visit));      for(i = 1; i < 6 ; i ++) have[num[i]] = 1;      for(i = 0 ; i < 12 ; i ++)      {          int x,y;          x = i / 4;          y = i % 4;          if(have[mpt[x][y]])          {              Count = 1;              mpt_visit[x][y] =1;              dfs_find(x,y);              break;          }      }      if(Count == 5)      {          ans ++;      }  }  //创建5个数的组合  void dfs_creat(int index)  {      if(index == 6)      {          Solve();          return;      }      for(int i = num[index-1] + 1; i < 13 ; i ++)      {          if(!visit[i])          {              visit[i] = true;              num[index] = i;              dfs_creat(index+1);              visit[i] = false;          }      }  }  int main()  {      init();      dfs_creat(1);      printf("%d\n",ans);      return 0;  }


这两段代码中都使用了数组dir[4][2]来检查相邻方格

可提炼如下:

int dir[4][2] = { 0, -1, -1, -1, -1, 0, -1, 1 };//i=0 dx = 0,dy = -1//i=1 dx = -1, dy = -1//i=2 dx = -1 dy = 0//i=3 dx = -1 dy = 1bool check(int x, int y, int n) //传入当前方格坐标及值{for (int i = 0; i < 4; i++){//遍历四个方向,按照Windows客户区的坐标方向依次是 上 左上 左 左下int nx = x + dir[i][0];int ny = y + dir[i][1]; //检查所遍历的方格是否超出范围if (nx >= 0 && nx < row && ny >= 0 && ny < col)   //if (nx < 0 || nx >= row || ny < 0 || ny >= col) continue; {//没超出范围要做的return true;}//其他要做的(如累加器、递归等)}return false;}





2 0
原创粉丝点击