思考一定少对着屏幕而是纸张和书本,不然效率会比较的低下。不要听歌!
真的是第一次凭着自己且没有看任何的东西做了一道dfs,感动。。。花费两个小时,继续加油鸭
整体收获:
1:还是对特殊情况的处理容易忽略,一开始写的代码不适用于T=1这种情况
2:一定要理清楚对矩阵的处理,传参数进dfs的时候,是不是存在换行的问题?
3:如果已经检测到(T,T)点(最后一个点),但是因为判断这个地方不能把参数传传进,那么就不会进入之后的dfs,就不会将cnt储蓄在num里面,这个
4:调试方法
本题花费较长时间之处:
1:在判断这个点是否可以放炮台的时候,仅仅判断了周围,没有判断这个点本身。考虑问题不严谨
2::检查到最后一个点的时候,没有储存cnt,判断结束程序
奉上我啰里啰唆的c++代码
#include <iostream>
#include <cstdio>
using namespace std;
int T;
char map[5][5];
int num[1000],n,cnt=0;//n记录的是有多少种方法,随着dfs将每个方法可以放的炮台的个数存在num里面
//cnt记录每个方法放置的炮台数
bool is(int x,int y)//检查是否可以放置炮台
{
if('p'==map[x][y] || 'X'==map[x][y]){
return false;
}
int i;
for(i=x-1;i>=1;i--){
if('X'==map[i][y]){
break;
}else if('p'==map[i][y]){
return false;
}
}
for(i=x+1;i<=T;i++){
if('X'==map[i][y]){
break;
}else if('p'==map[i][y]){
return false;
}
}
for(i=y-1;1<=i;i--){
if('X'==map[x][i]){
break;
}else if('p'==map[x][i]){
return false;
}
}
for(i=y+1;i<=T;i++){
if('X'==map[x][i]){
break;
}else if('p'==map[x][i]){
return false;
}
}
return true;
}
????
void dfs(int x,int y,int cnt)//cnt是放置了多少炮台
{
if(T+1==x){//已经遍历结束
num[n++]=cnt;
return;
}
int i=0,j=0;
for(i=x;i<=T;i++){//直接从上次放炮台的下一个地方开始检查
if(0==j) j=y;//开始接着上次的地方遍历
else j=1;//上次那个地方的一行已经处理完毕,再重新开一行j=1
for(j;j<=T;j++){//判断是否到最后一个点,到最后一个点并别这个点不能放炮台,就dfs,结束程序
if(T==i && T==j && !is(i,j)){
dfs(i+1,1,cnt);
}
if(is(i,j)){//先检查是否能放炮台
map[i][j]='p';//放置炮台
cnt++;//放置数+1;
if(T==j){
dfs(i+1,1,cnt);
}else{
dfs(i,j+1,cnt);
}
cnt--;//放置数-1
map[i][j]='.';//褪去标记
}
}
}
}
int main()
{
while(cin >> T && T)
{
if(1==T){
char temp;
cin >> temp;
cout << 1 << endl;
continue;
}
int i,j;
for(i=1;i<=T;i++){
for(j=1;j<=T;j++){
cin >> map[i][j];
}
}
n=0,cnt=0;
dfs(1,1,cnt);
int max=0;
for(i=0;i<n-1;i++){
if(max<num[i]){
max=num[i];
}
}
cout << max << endl ;
}
return 0;
}