BNUOJ 4299 God Save the i-th Queen(想法题)
题目链接==》 http://www.bnuoj.com/v3/problem_show.php?pid=4299
题意:一个X*Y棋盘上放了N个queens,再放一个queen,有几个空格可以放,前提是和已经在棋盘上的queen不同行不同列不同斜线
思路:每个点所在四条直线上,不能再放queen,所以将有点的直线标记,再遍历所有点,如果点所在直线已被标记,则不选。(完了)
代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<iostream> 5 6 using namespace std; 7 8 const int T=4e4+9; 9 10 int h[T],l[T],xie_1[T],xie_2[T];///xie_1表示斜率大于0的直线 11 int sum,n,m; 12 13 void begin1( ) 14 { 15 sum=0; 16 memset(h, 0 , sizeof( int )*T); 17 memset(l, 0 , sizeof( int )*T); 18 memset(xie_1, 0 , sizeof( int )*T); 19 memset(xie_2, 0 , sizeof( int )*T); 20 } 21 22 void judge( int x, int y) 23 { 24 int w; 25 h[x]=1; l[y]=1; 26 xie_1[x+y+1]=1; 27 w=m+1-y; /// 标记斜率为负的棋盘,则将列标号倒置,从m-->1,所以这个点所在直线也是L(x+w+1) 28 xie_2[x+w+1]=1; 29 } 30 31 void judge_two( int x, int y ) 32 { 33 int w=m+1-y; 34 if( h[x] || l[y] || xie_1[x+y+1] || xie_2[x+w+1] ) 35 return ; 36 sum++; 37 38 } 39 40 41 42 43 int main( ) 44 { 45 int k,a,b; 46 while(scanf("%d%d%d",&n,&m,&k),(n+m+k)) 47 { 48 begin1( ); 49 for(int i=1;i<=k;i++) 50 { 51 scanf("%d%d",&a,&b); 52 judge( a, b ); 53 } 54 for(int i=1;i<=n;i++) 55 for(int j=1;j<=m;j++) 56 judge_two( i, j ); 57 printf("%d\n",sum); 58 } 59 return 0; 60 }