又見皇后 | ||||||
|
||||||
Description | ||||||
國際象棋中,皇后能攻擊同一橫線、同一豎線、同一斜線(45度)的敵人。
衆所周知,有一個非常著名的算法問題,是求在一個n×n的國際象棋棋盤中最多能擺放多少個皇后,使其不能相互攻擊。 今天我們暫且不要讓問題如此理想化。假設棋盤上有一些障礙物,皇后不能擺在障礙物上,同時也不能穿過障礙物攻擊別人。在此條件之下,棋盤上最多又能放多少個皇后?
圖中黑色方塊表示障礙物,圓點表示皇后 圖2是一種最優擺法;圖4、圖5屬於違規擺法 |
||||||
Input | ||||||
輸入包含多組數據。
每組數據的第一行是一個整數n(1≤n≤8),表示棋盤的邊長。之後的n行將描述棋盤,其中’X’表示該單元格有障礙物,’.’則表示沒有。 n=0表示輸入結束。 |
||||||
Output | ||||||
對於每組數據,請輸出一個整數表示最多能在棋盤上放幾個皇后,使它們相互不能攻擊。 每個答案佔一行。 |
||||||
Sample Input | ||||||
4
.X.. ...X XXX. ..X. 2 XX .X 3 .X. X.X .X. 0 |
||||||
Sample Output | ||||||
4
1 2 |
數據給的小/。。
時間也多。。
直接暴力跑。。
因爲有阻隔點所以一行可能存在不止一個點。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define N 10
int res;
int n;
int m;
char maps[N][N];
int vis[N][N];
int judge(int x,int y)
{
for(int i=y-1; i>=0&&maps[x][i]=='.'; i--)
if(vis[x][i]==1)
return 0;
for(int i=x-1; i>=0&&maps[i][y]=='.'; i--)
{
if(vis[i][y]==1)
return 0;
}
for(int i=x-1,j=y-1; i>=0&&maps[i][j]=='.'&&j>=0; j--,i--)
{
if(vis[i][j]==1)
return 0;
}
for(int i=x-1,j=y+1; i>=0&&maps[i][j]=='.'&&j<n; j++,i--)
{
if(vis[i][j]==1)
return 0;
}
return 1;
}
void dfs(int pos,int tmp)
{
if(pos>=m)
return ;
if(res<tmp)
{
res=tmp;
}
pos++;
dfs(pos,tmp);
if(maps[pos/n][pos%n]=='.'&&judge(pos/n,pos%n))
{
vis[pos/n][pos%n]=1;
dfs(pos,tmp+1);
vis[pos/n][pos%n]=0;
}
return ;
}
int main()
{
while(scanf("%d",&n),n)
{
res=0;
memset(vis,0,sizeof(vis));
for(int i=0; i<n; i++)
{
scanf("%s",maps[i]);
}
m = n*n;
if(maps[0][0]=='.')
{
vis[0][0]=1;
dfs(0,1);
vis[0][0]=0;
}dfs(0,0);
printf("%d\n",res);
}
}