P1274 魔术数字游戏

守給你的承諾、 提交于 2019-11-30 06:18:13

题目描述

填数字方格的游戏有很多种变化,如下图所示的4×4方格中,我们要选择从数字1到16来填满这十六个格子(Aij,其中i=1..4,j=1..4)。为了让游戏更有挑战性,我们要求下列六项中的每一项所指定的四个格子,其数字累加的和必须为34:

四个角落上的数字,即A11+A14+A41+A44=34。

每个角落上的2×2方格中的数字,例如左上角:A11+A12+A21+A22=34。

最中间的2×2方格中的数字,即A22+A23+A32+A33=34。

每条水平线上四个格子中的数字,即Ai1+Ai2+Ai3+Ai4=34,其中i=1..4。

每条垂直线上四个格子中的数字,即A1j+A2j+A3j+A4j=34,其中j=1..4。

两条对角线上四个格子中的数字,例如左上角到右下角:A11+A22+A33+A44=34。

右上角到左下角:A14+A23+A32+A41=34

输入格式

输入文件会指定把数字1先固定在某一格内。输入的文件只有一行包含两个正数据I和J,表示第1行和第J列的格子放数字1。剩下的十五个格子,请按照前述六项条件用数字2到16来填满。

输出格式

把全部的正确解答用每4行一组写到输出文件,每行四个数,相邻两数之间用一个空格隔开。两组答案之间,要以一个空白行相间,并且依序排好。排序的方式,是先从第一行的数字开始比较,每一行数字,由最左边的数字开始比,数字较小的解答必须先输出到文件中。

输入输出样例

输入 #1
1 1  
输出 #1
1 4 13 16  14 15 2 3  8 5 12 9  11 10 7 6    1 4 13 16  14 15 2 3  12 9 8 5  7 6 11 10首先为了方便计算我们显然要把一个格子的两个坐标压成一个整数。具体计算方法将(i,j)(i,j)转换为(i-1)\times4+j-1(i−1)×4+j−1。然后,打一发表。。。。。。好的,结了。
#include <cstdio>    int b[15][4] = {      {0, 1, 2, 3},      {4, 5, 6, 7},      {8, 9, 10, 11},      {12, 13, 14, 15},      {0, 4, 8, 12},      {1, 5, 9, 13},      {2, 6, 10, 14},      {3, 7, 11, 15},      {0, 5, 10, 15},      {3, 6, 9, 12},      {5, 6, 9, 10},      {0, 1, 4, 5},      {2, 3, 6, 7},      {8, 9, 12, 13},      {10, 11, 14, 15}  };    int a[16];  int vis[17];  int xz[16][10];  int cnt[16];  int pos1;    void DFS(int num){      if (num == 16){          if (a[pos1] != 1) return ;          for (int i = 0; i < 4; ++i) printf("%d%c", a[i], ((i == 3) ? '\n' : ' '));          for (int i = 4; i < 8; ++i) printf("%d%c", a[i], ((i == 7) ? '\n' : ' '));          for (int i = 8; i < 12; ++i) printf("%d%c", a[i], ((i == 11) ? '\n' : ' '));          for (int i = 12; i < 16; ++i) printf("%d%c", a[i], ((i == 15) ? '\n' : ' '));          puts("");          return ;      }      a[num] = 0;      for (int i = 0; i < cnt[num]; ++i){          if (!a[num]){              a[num] = 34 - a[b[xz[num][i]][0]] - a[b[xz[num][i]][1]] - a[b[xz[num][i]][2]];              if (a[num] > 16 || a[num] < 1) return ;              if (a[num] == 1 && num != pos1) return ;              if (vis[a[num]]) return ;          }          else{              if (a[num] != 34 - a[b[xz[num][i]][0]] - a[b[xz[num][i]][1]] - a[b[xz[num][i]][2]]) return ;          }      }      if (!a[num]){          if (num == pos1){              if (vis[1]) return ;              vis[1] = 1; a[num] = 1;              DFS(num + 1);              vis[1] = 0;          }          else{              for (int i = 2; i <= 16; ++i){                  if(vis[i]) continue;                  vis[i] = 1; a[num] = i;                  DFS(num + 1);                  vis[i] = 0;              }          }      }      else{          if (num == pos1 && a[num] != 1) return ;          vis[a[num]] = 1;          DFS(num + 1);          vis[a[num]] = 0;      }  }    int main(){      int x, y; scanf("%d %d", &x, &y); pos1 = (x - 1) * 4 + y - 1;      for (int i = 0; i < 15; ++i){          xz[b[i][3]][cnt[b[i][3]]++] = i;      }      DFS(0);      return 0;  }

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!