天天看點

一大堆的福利之【USACO題庫】Checker Challenge跳棋的挑戰

題目描述

檢查一個如下的6 x 6的跳棋棋盤,有六個棋子被放置在棋盤上,使得每行,每列,每條對角線(包括兩條主對角線的所有對角線)上都至多有一個棋子。 

列号

1 2 3 4 5 6

-------------------------

1 | | O | | | | |

-------------------------

2 | | | | O | | |

-------------------------

3 | | | | | | O |

-------------------------

4 | O | | | | | |

-------------------------

5 | | | O | | | |

-------------------------

6 | | | | | O | |

-------------------------

上面的布局可以用序列2 4 6 1 3 5來描述,第i個數字表示在第i行的相應位置有一個棋子,如下: 

行号 1 2 3 4 5 6 

列号 2 4 6 1 3 5 

這隻是跳棋放置的一個解。請遍一個程式找出所有跳棋放置的解。并把它們以上面的序列方法輸出。解按字典順序排列。請輸出前3個解。最後一行是解的總個數。 

特别注意: 對于更大的N(棋盤大小N x N)你的程式應當改進得更有效。不要事先計算出所有解然後隻輸出,這是作弊。如果你堅持作弊,那麼你登陸USACO Training的帳号将被無警告删除

PROGRAM NAME: checker

INPUT FORMAT

一個數字N (6 <= N <= 13) 表示棋盤是N x N大小的。

SAMPLE INPUT(checker.in) 

6

OUTPUT FORMAT

前三行為前三個解,每個解的兩個數字之間用一個空格隔開。第四行隻有一個數字,表示解的總數。

SAMPLE OUTPUT(checker.out)

2 4 6 1 3 5 

3 6 2 5 1 4 

4 1 5 2 6 3 

4

var n,ans,i,j,temp:longint;
  a:array[..] of longint;
  f:array[..,..] of longint;
  x,y,z:array[-..] of boolean;
procedure queen(q:longint);
var i:longint;
begin
     if q=n+ then
     begin
        inc(ans);inc(temp);
        if temp< then
           for i:= to n do f[temp,i]:=a[i];
     end else
        for i:= to n do
            if(not x[i])and(not y[i-q])and(not z[i+q])then
            begin
                x[i]:=true;y[i-q]:=true;z[i+q]:=true;a[q]:=i;queen(q+);
                x[i]:=false;y[i-q]:=false;z[i+q]:=false;
            end;
end;
begin
     readln(n);queen();
     for i:= to  do
     begin
         for j:= to n do write(f[i,j],' ');
         writeln;
     end;
     writeln(ans);
end.