zoj 1002 vry good
输入一个N,和N*N的棋盘布局,放入守卫,要求同行同列不能放置,如果遇到障碍物则可以放置,问最多可以放多少守卫。(原题地址:http://acm.zju.edu.cn/show_problem.php?pid=1002)
如第一个图为棋盘布局,第2个图为放置5个守卫(最多),第3个图合格但不是最多的,第4 5个图不合格。
输入:先输入一个N,下面N行为棋盘布局,'.'代表畅通,'X'代表障碍物.
遇到0代表结束.
输出:对于每个棋盘,输出可以放置的最多守卫数.
Sample input:
4
.X..
....
XX..
....
2
XX
.X
3
.X.
X.X
.X.
3
...
.XX
.XX
4
....
....
....
....
0
Sample output:
5
1
5
2
4
这道题和8皇后问题有点像,就是用DFS搜索,我先还以为用动态规划,想半天递推公式没想出来。。
1/*zju 1002
2by woodfish
3*/
4#include<iostream>
5using namespace std;
6
7char map[5][5];
8int n;
9int mmax;
10
11void init(){
12 int i,j;
13 for(i=0;i<n;i++) {
14 for(j=0;j<n;j++)
15 cin>>map[i][j];
16 }
17}
18
19int Putcan(int col,int row){
20 int i,j;
21 for(i=row-1;i>=0;i--) {
22 if(map[col][i]=='0')
23 return 0;
24 else if(map[col][i]=='X')
25 break;
26 }
27 for(j=col-1;j>=0;j--) {
28 if(map[j][row]=='0')
29 return 0;
30 else if(map[j][row]=='X')
31 break;
32 }
33 return 1;
34}
35
36void Slove(int pos,int ccount){
37 int col,row;
38 if(pos==n*n) {
39 if(mmax<ccount)
40 mmax=ccount;
41 return;
42 }
43 col=pos/n;
44 row=pos%n;
45 if(map[col][row]=='.'&&Putcan(col,row)) {
46 map[col][row]='0';
47 Slove(pos+1,ccount+1);
48 map[col][row]='.';
49 }
50 Slove(pos+1,ccount);
51}
52
53int main(){
54 while(cin>>n&&n) {
55 mmax=0;
56 init();
57 Slove(0,0);
58 cout<<mmax<<endl;
59 }
60 return 0;
61}
代码
#include<iostream>
#include<string>
using namespace std;
bool STOP;
typedef struct point
{
char data;
bool isplaced;
int count;
} datatype;
datatype line[4][4];
int All=0;
void input(int n)
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
cin>>line[i][j].data;
line[i][j].isplaced=false;
line[i][j].count=0;
}
}
bool ifcanplace(int n,int i,int j) //能否放置
{
int ii=j,jj=i;//chushihua????
int ii1=j,jj1=i;
bool flag1=false,flag2=false;
for(int ix=0;ix<n;ix++)
{
if(line[i][ix].data=='X'){ii=ix;}
if(line[i][ix].isplaced&&(line[i][ix].data=='O')&&!flag1){ii1=ix;flag1=true;}
}
for(int iy=0;iy<n;iy++)
{
if(line[iy][j].data=='X'){jj=iy;}
if(line[iy][j].isplaced&&(line[iy][j].data=='O')&&!flag2){jj1=iy;flag2=true;}
}
if(flag1&&flag2)
{if(((ii>j&&ii<ii1)||(ii>ii1&&ii<j))&&((jj>i&&jj<jj1)||(jj>jj1&&jj<i))) return true; return false;}//wrong!
if(flag1)
{ if(ii==j) return false;
if((ii>j&&ii<ii1)||(ii>ii1&&ii<j)) return true;
return false;
}
if(flag2)
{ if(jj==i) return false;
if((jj>i&&jj<jj1)||(jj>jj1&&jj<i)) return true;
return false;
}
if(!flag1&&!flag2) return true;
return false;
}
bool place(int n) //寻找放置位置
{
int ibest=-1,jbest=-1;
for(int i1=0;i1<n;i1++)
for(int j1=0;j1<n;j1++)
line[i1][j1].count=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if (line[i][j].data=='.'&&!line[i][j].isplaced)
{
if(i>0) {if(line[i-1][j].data=='X') line[i][j].count+=1;if(line[i-1][j].isplaced&&line[i-1][j].data=='O') line[i][j].count=-1;}//error1
if(i<n-1) {if(line[i+1][j].data=='X')line[i][j].count+=1;if(line[i+1][j].isplaced&&line[i+1][j].data=='O') line[i][j].count=-1;}
if(j>0) {if(line[i][j-1].data=='X') line[i][j].count+=1;if(line[i][j-1].isplaced&&line[i][j-1].data=='O') line[i][j].count=-1;}
if(j<n-1) {if(line[i][j+1].data=='X') line[i][j].count+=1;if(line[i][j+1].isplaced&&line[i][j+1].data=='O') line[i][j].count=-1;}
}
}
}
int max=-1;
for(i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(line[i][j].data=='.'&&(!line[i][j].isplaced)&&(line[i][j].count>max))
{
max=line[i][j].count;
ibest=i;
jbest=j;
}
}
if(ibest==-1||jbest==-1) return false;
if(ifcanplace(n,ibest,jbest))
{
All++;
line[ibest][jbest].data='O';
}
line[ibest][jbest].isplaced=true;
return true;
}
int main()
{
int m;
while(cin>>m&&m!=0)
{
STOP=false;
All=0;
input(m);
for(int i=0;i<m;i++)
for(int j=0;j<m;j++)
place(m);
cout<<All<<endl;
}
return 0;
}