sgf87

zoj 1002 vry good

zju 1002

输入一个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;

}

 

 

 

posted on 2010-04-26 16:29  sgf87  阅读(293)  评论(0编辑  收藏  举报

导航