裸搜索题
每行搜一个可行位置,标记列避免判断(区别看现在的代码和以前的代码)
详见代码
搜索题要注意细节,用一些小技巧,不要死代码太长这样容易错。
现在的代码
#include
#include
#include
using namespace std;
char str[10][10];
bool a[10];//a[i]表示第i列是否已经放过了棋子
int ans;
int n, m;
//cnt表示行数(从0开始),val表示放棋子的个数
void dfs(int cnt, int val)
{
if(val == m)//当放了m个棋子后增加一种可能
{
ans++;
return ;
}
if(cnt == n) return;//超过行数时直接返回
int i;
dfs(cnt+1, val);
for(i = 0; i < n; i++)
{
if(str[cnt][i] == '#' && !a[i])
{
a[i] = 1;//标记第i列已经放了棋子
dfs(cnt+1, val+1);
a[i] = 0;//还原
}
}
}
int main(void)
{
while(scanf("%d%d", &n, &m), n+m>0)
{
int i;
memset(a, 0, sizeof(a));
for(i = 0; i < n; i++)
scanf("%s", str[i]);
ans = 0;
dfs(0, 0);
printf("%d\n", ans);
}
return 0;
}
以前的代码
#include
#include
#include
using namespace std;
const int N = 10;
char a[N][N];
int b[N];
int n, k;
vector
g[N];
int judge(int cnt)
{
int i;
for(i = 1; i < cnt; i++)
{
if(b[i] == b[cnt]) return 0;
}
return 1;
}
void debug(int n)
{
for(int i = 1; i < n; i++)
printf("%d ", b[i]);
printf("\n");
}
int dfs(int cnt, int kk)
{
// printf("cnt=%d\tkk=%d\n", cnt, kk);
// debug(kk);
if(kk > k) return 1;
if(cnt > n) return 0;
int i;
int ans = 0;
for(i = 0; i < g[cnt].size(); i++)
{
b[kk] = g[cnt][i];
if(judge(kk)) ans += dfs(cnt+1, kk+1);
}
ans += dfs(cnt+1, kk);
return ans;
}
int main(void)
{
int i, j;
while(scanf("%d%d", &n, &k) && (n!=-1||k!=-1))
{
for(i = 1; i <= n; i++)
scanf("%s", a[i]+1);
for(i = 1; i <= n; i++)
{
// printf("%s", a[i]);
g[i].clear();
for(j = 1; j <= n; j++)
{
if(a[i][j] == '#') g[i].push_back(j);
}
// for(j = 0; j < g[i].size(); j++)
// printf("%d ", g[i][j]);printf("\n");
}
printf("%d\n", dfs(1, 1));
}
return 0;
}