zoj 2778 - Triangular N-Queens Problem
阿新 • • 發佈:2017-06-05
tracking set 成功 皇後 ont pri problem 分析 angular
題目:在三角形的棋盤上放n皇後問題。
分析:找規律題目。依照題目的輸出,能夠看出構造法則;
先填奇數,後填偶數。以下我們僅僅要證明這樣的構造的存在性就可以。
解法:先給出集體構造方法,從(1。n-f(n)+1) 開始填充奇數點;
填充全部的(1+2k。n-f(n)+1+k){當中f(n)就是最大填充數。1+2k<=n-f(n)+1+k} 。
之後開始從(2。n-f(n)+1+k+1)開始填充偶數點,因為奇數點僅僅能攻擊奇數點。
偶數點僅僅能攻擊偶數點,所以僅僅要保證每行一個皇後就能夠了。
證明:我們僅僅須要證明從第n-f(n)+1行開始。每行都能夠放一個皇後就能夠了;
首先。依照上面的構造可知,如此構造。皇後是不能夠互相攻擊的。
然後,因為第i行有i個元素。所以有 1+2k<=n-f(n)+1+k。
解得。k <= n-f(n)>= f(n)/2,因此至少有一半是奇數點;
偶數點僅僅要插入到奇數點之間就能夠構造了。構造成功。
說明:(2011-09-19 01:28)。
#include <stdio.h> #include <stdlib.h> #include <string.h> bool M[ 1001 ][ 1001 ]; int F[ 1005 ]; int A[ 668 ]; int B[ 668 ]; int main() { /* 遞推公式 memset( F, 0, sizeof( F ) ); F[ 0 ] = 0;F[ 1 ] = 1;F[ 2 ] = 1; for ( int i = 3 ; i <= 1000 ; ++ i ) F[ i ] = F[ i-3 ] + 2; */ for ( int i = 1 ; i <= 1000 ; ++ i ) F[ i ] = (2*i+1)/3; int c,n; while ( scanf("%d",&c) != EOF ) for ( int t = 1 ; t <= c ; ++ t ) { memset( M, 0, sizeof( M ) ); scanf("%d",&n); printf("%d %d %d\n",t,n,F[ n ]); int y = n-F[ n ]+1; int x = 1; for ( int i = 0 ; i < F[ n ] ; ++ i ) { A[ i ] = y;B[ i ] = x; M[ y ][ x ] = 1; y += 1;x += 2; if ( x > y ) x = 2; } /* 畫圖部分 for ( int p = 1 ; p <= n ; ++ p ) { for ( int q = 0 ; q < n-p ; ++ q ) printf(" "); for ( int q = 1 ; q <= p ; ++ q ) if ( M[ p ][ q ] ) printf("* "); else printf("@ "); printf("\n"); } */ printf("[%d,%d]",A[ 0 ],B[ 0 ]); for ( int i = 1 ; i < F[ n ] ; ++ i ) { if ( i%8 == 0 ) printf("\n"); else printf(" "); printf("[%d,%d]",A[ i ],B[ i ]); } printf("\n\n"); } return 0; }
zoj 2778 - Triangular N-Queens Problem