杭电acm1045,AC了,还是参考了别人的代码才过的。有点收获,觉得,有必要写一下感想。
这道题目,总体有2种情况会改变。每一个点,如果不插入,是一种情况,如果插入了,就会引发另外一种情况。我们要将每一个点的这2种情况都遍历分析一遍。
这道题目,开始的时候,要遍历一下所有点,判断每一个是不是可以插入,如果满足插入条件的话,就插入,修改了矩阵。在这种情况下,开始遍历下一个点。在这种情况下,遍历完所有点之后,记录最大值。
记得要回溯,将该点搞成原来的样子,再分析不插入的情况(这个时候,没什么好分析的)那样的话,我们就可以直接跳下面一个点了,重复上面的步骤,就可以了。
貌似,这个就是贪心的想法吧。
代码如下:
import java.util.Scanner;
public class Main
{
public byte a[][]; //表示矩阵
private int n;
private int max;
Main( int n )
{
this.n = n;
a = new byte[n][n];
max = 0;
}
public boolean isInsert( int row,int column ) //判断这一个点可不可以插入
{
boolean h=true;
boolean v=true;
for( int i=column-1;i>=0;i-- ) //判断这一行是不是可以插入
{
if( a[row][i]=='Z' ) //这一行已经插入了
{
h = false;
break;
}
if( a[row][i]=='X' )
{
h = true;
break;
}
}
for( int j=row-1;j>=0;j-- ) //判断这一列是不是可以插入
{
if( a[j][column]=='Z' ) //这一列已经插入了
{
v = false;
break;
}
if( a[j][column]=='X' ) //这一列有阻隔
{
v = true;
break;
}
}
return (h&&v);
}
public void setMax( int k,int cur ) //找出最大值
{
if( k==n*n ) //遍历超出最后一个地方
{
if( max<cur )
max = cur;
return;
}
int row = k/n;
int column = k%n;
if( a[row][column]=='.' ) //插入之后,开始
{
if( this.isInsert(row,column) )
{
a[row][column] = 'Z';
setMax( k+1,cur+1 );
//回溯
a[row][column] = '.';
}
}
//由于上面有回溯一遍,所以,如果第k个点插入的话,它会插入然后不断递归进去,然后恢复原状。
//如果第k个点没有插入,这个点就遍历过了,继续遍历第k+1个点
setMax( k+1,cur );
}
public void prMax()
{
System.out.println( this.max );
}
public static void main(String[] args)
{
int n;
Scanner s = new Scanner(System.in);
n = s.nextInt();
int i = 0;
int j = 0;
String str;
while( n!=0 )
{
Main m = new Main( n );
for( i=0;i<n;i++ )
{
str = s.next();
byte[] b = str.getBytes();
for( j=0;j<n;j++ )
{
m.a[i][j] = b[j];
}
}
m.setMax(0,0);
m.prMax();
n = s.nextInt();
}
}
}