fork download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4.  
  5. // ------- 可変設定 --------
  6. #define SIZE 8 // グリッド全体のサイズ(例: 4, 6, 9)
  7. #define BLOCK_H 2 // ブロックの縦のサイズ(例: 2)
  8. #define BLOCK_W 4 // ブロックの横のサイズ(例: 3)
  9. // -------------------------
  10.  
  11. int grid[SIZE][SIZE];
  12.  
  13. // ランダムな順番に並び替え
  14. void shuffle(int *array, int size) {
  15. for (int i = size - 1; i > 0; i--) {
  16. int j = rand() % (i + 1);
  17. int tmp = array[i];
  18. array[i] = array[j];
  19. array[j] = tmp;
  20. }
  21. }
  22.  
  23. // num を (row, col) に置いていいか判定
  24. int isSafe(int row, int col, int num) {
  25. for (int x = 0; x < SIZE; x++) {
  26. if (grid[row][x] == num || grid[x][col] == num)
  27. return 0;
  28. }
  29.  
  30. int startRow = row - row % BLOCK_H;
  31. int startCol = col - col % BLOCK_W;
  32.  
  33. for (int i = 0; i < BLOCK_H; i++) {
  34. for (int j = 0; j < BLOCK_W; j++) {
  35. if (grid[startRow + i][startCol + j] == num)
  36. return 0;
  37. }
  38. }
  39.  
  40. return 1;
  41. }
  42.  
  43. // 再帰的に埋めていく
  44. int fillGrid(int row, int col) {
  45. if (row == SIZE - 1 && col == SIZE)
  46. return 1;
  47. if (col == SIZE) {
  48. row++;
  49. col = 0;
  50. }
  51.  
  52. if (grid[row][col] != 0)
  53. return fillGrid(row, col + 1);
  54.  
  55. int nums[SIZE];
  56. for (int i = 0; i < SIZE; i++) nums[i] = i + 1;
  57. shuffle(nums, SIZE);
  58.  
  59. for (int i = 0; i < SIZE; i++) {
  60. int num = nums[i];
  61. if (isSafe(row, col, num)) {
  62. grid[row][col] = num;
  63. if (fillGrid(row, col + 1))
  64. return 1;
  65. grid[row][col] = 0;
  66. }
  67. }
  68.  
  69. return 0;
  70. }
  71.  
  72. // 出力関数
  73. void printGrid() {
  74. for (int i = 0; i < SIZE; i++) {
  75. for (int j = 0; j < SIZE; j++) {
  76. printf("%2d ", grid[i][j]);
  77. }
  78. printf("\n");
  79. }
  80. }
  81.  
  82. int main() {
  83. srand(time(NULL));
  84.  
  85. // 初期化
  86. for (int i = 0; i < SIZE; i++)
  87. for (int j = 0; j < SIZE; j++)
  88. grid[i][j] = 0;
  89.  
  90. if (fillGrid(0, 0)) {
  91. printf("完成済みのナンプレ (%dx%d, %dx%dブロック):\n", SIZE, SIZE, BLOCK_H, BLOCK_W);
  92. printGrid();
  93. } else {
  94. printf("グリッドを生成できませんでした。\n");
  95. }
  96.  
  97. return 0;
  98. }
Success #stdin #stdout 0.01s 5336KB
stdin
Standard input is empty
stdout
完成済みのナンプレ (8x8, 2x4ブロック):
 6  4  8  5  2  7  3  1 
 3  1  7  2  8  6  5  4 
 5  2  3  4  7  1  8  6 
 8  7  6  1  5  4  2  3 
 7  3  1  8  4  5  6  2 
 4  5  2  6  3  8  1  7 
 1  8  4  3  6  2  7  5 
 2  6  5  7  1  3  4  8