質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

3回答

4108閲覧

C言語でのNクイーン問題が解けません

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2020/07/02 03:11

プログラミング初心者です。
c言語を独学で進めていたのですが、Nクイーン問題で行き詰りました。
以下のようなコードを書いたのですが、問題点がわかりません。出力が以下のようになる理由はわかるのですが、どこをどう改善すればいいのかわかりません。

出力:
Q*******
Q*******
Q*******
Q*******
Q*******
Q*******
Q*******
Q*******

ご教授願います。

該当のソースコード

C言語

#include<stdio.h> #include<stdlib.h> #define N 8 enum {queen = 1, non = 0}; int output(int a[N][N]){ for (int i=0; i<N; i++){ for (int j=0; j<N; j++){ if (a[i][j] == non) putchar('*'); else putchar('Q'); } putchar('\n'); } return 0; } int can_choose(int a[N][N], int i, int j){ int x, y; for(x=j-1, y=i-1; x>=0 && y>=0; x--,y--) if(a[y][x] == queen) return 0; for(x=j-1, y=i; x>=0 ; x--) if(a[y][x] == queen) return 0; for(x=j-1, y=i+1; x>=0 && y<0; x--,y++) if(a[y][x] == queen) return 0; return 1; } int solve(int board[N][N], int x){ int y = 0; for(y = 0 ; y < N; y++){ board[x][y] = queen; //back track if (can_choose(board, x, y) == 0) return 0; // base case if (can_choose(board, x, y) == 1 && x == N){ output(board); } //recursive case solve(board, x+1); } } int main(){ int x=0; int y=0; int board[N][N]; for (x=0; x<N; x++){ for (y=0; y<N; y++){ board[x][y] = non; } } solve(board, 0 ); return 0; }

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

こんにちは。
スマートフォンから失礼します。

初投稿ですが、この問題、Nが8のとき、
92個が正解だったと思います。

コードは持っていますが貼り付け方がわからず、
スミマセン。あまりに有名な問題だったもので。

投稿2020/07/02 16:18

Diovany

総合スコア6

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

まずはデバッグできる環境を揃えましょう
Eclipseや、WindowsならVisualStudioなど。
コードの任意の行で実行を止め、変数の中身を参照できます。
また、そこから1行づつ実行させてコードの流れや変数の変化を見ることができます

そうすれば、アテずっぽでコードを書かなくて済むようになり、
なぜ動かないか他人に聞くようなこともしないで済むようになります

投稿2020/07/02 07:55

y_waiwai

総合スコア88042

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

main では a[x][y]、can_choose では a[y][x] になっています。
can_choose の 3つめの for文の y<0 は常に成立しません。
solve も変です。boad[x][y] = queen; はしているのに、
non に戻す処理がありません。

ということで、書き直してみました。

C

1#include <stdio.h> 2 3#define N 8 4 5enum { queen = 1, non = 0 }; 6 7int output(int a[N][N]) 8{ 9 for (int i = 0; i < N; i++) { 10 for (int j = 0; j < N; j++) { 11 if (a[i][j] == non) printf(" *"); 12 else printf(" Q"); 13 } 14 putchar('\n'); 15 } 16 putchar('\n'); 17 return 0; 18} 19 20int can_choose(int a[N][N], int i, int j) 21{ 22 int x, y; 23 24 for (x = i - 1, y = j - 1; x >= 0 && y >= 0; x--, y--) 25 if (a[x][y] == queen) return 0; 26 27 for (x = i - 1, y = j; x >= 0; x--) 28 if (a[x][y] == queen) return 0; 29 30 for (x = j - 1, y = i + 1; x >= 0 && y < N; x--, y++) 31 if (a[x][y] == queen) return 0; 32 33 return 1; 34} 35 36int solve(int board[N][N], int x) 37{ 38 if (x == N) 39 output(board); 40 else { 41 for (int y = 0; y < N; y++) { 42 if (can_choose(board, x, y)) { 43 board[x][y] = queen; 44 solve(board, x + 1); 45 board[x][y] = non; 46 } 47 } 48 } 49} 50 51int main(void) 52{ 53 int board[N][N]; 54 for (int x = 0; x < N; x++) { 55 for (int y = 0; y < N; y++) { 56 board[x][y] = non; 57 } 58 } 59 solve(board, 0); 60 return 0; 61}

追記
別解を考えて書いてみたら、92個のパターンが出てきました。
ところが、最初のコードは、650個出てきて間違ったものが含まれています。
どこが間違っているのか調査したいんですが、ちょっと別件の用事があって
しばらく時間をください。

別解

C

1#include <stdio.h> 2 3#define N 8 4 5void output(int a[]) 6{ 7 for (int i = 0; i < N; i++) { 8 for (int j = 1; j <= N; j++) { 9 if (a[i] == j) printf(" Q"); 10 else printf(" *"); 11 } 12 putchar('\n'); 13 } 14 putchar('\n'); 15} 16 17int can_choose(int a[], int x, int y) 18{ 19 for (int i = x - 1, p = 1; i >= 0; i--, p++) 20 if (a[i] == y || a[i] - p == y || a[i] + p == y) return 0; 21 return 1; 22} 23 24void solve(int board[], int x) 25{ 26 if (x == N) 27 output(board); 28 else { 29 for (int y = 1; y <= N; y++) { 30 if (can_choose(board, x, y)) { 31 board[x] = y; 32 solve(board, x + 1); 33 board[x] = 0; 34 } 35 } 36 } 37} 38 39int main(void) 40{ 41 int board[N] = { 0 }; 42 solve(board, 0); 43}

追記2
can_choose の 3番目の for文が間違っていました。
次のように訂正します。

diff

1- for (x = j - 1, y = i + 1; x >= 0 && y < N; x--, y++) 2+ for (x = i - 1, y = j + 1; x >= 0 && y < N; x--, y++)

追記3
別解の can_choose をちょっと変更。

diff

1- for (int i = x - 1, p = 1; i >= 0; i--, p++) 2- if (a[i] == y || a[i] - p == y || a[i] + p == y) return 0; 3+ for (int p = 1; --x >= 0; p++) 4+ if (a[x] == y || a[x] - p == y || a[x] + p == y) return 0;

投稿2020/07/02 07:44

編集2020/07/02 16:39
kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問