Problem A:棋盘问题
题目大意:给N*N大小棋盘,M个棋子,问要将棋子放在棋盘中的’#’位置有几种方法..
思路:按行回溯搜索..
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int n, k, sum;
char m[10][10];
bool col[10]; //记录行状态
void dfs(int cur, int cnt) {
if(cnt == 0) {
sum++; //若棋子恰好放置完全,则方法数加一
}
for(int i = cur + 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
if(m[i][j] == '#' && col[j] == false) {
col[j] = true; //该行已放置棋子
dfs(i, cnt - 1); //放置后进入i层搜索
col[j] = false; //用于回溯
}
}
}
}
int main() {
while(scanf("%d %d", &n, &k) != EOF) {
sum = 0;
if(n == -1 && k == -1) {
break;
}
for(int i = 1; i <= n; i++) {
scanf("%s", m[i] + 1);
}
memset(col, false, sizeof col);
dfs(0, k); //从0行开始搜索
printf("%d\n", sum);
}
return 0;
}
Problem B:Find The Multiple
题目大意 :找出某个数的倍数且该倍数只由0和1组成..
思路:计算发现,答案其实可以用ull存放,枚举0和1,DFS..
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
int n;
unsigned long long ans; //测试数据过大,需使用ull存储
bool flag;
void dfs(unsigned long long cur, int deep) { //deep为我们搜索数字的长度
if(cur % n == 0) { //若找到可以进行整除操作的数,则退出
flag = true;
ans = cur;
return ;
}
if(deep == 19) return ; //由样例输出得知,答案最长18位,若越界则退出
if(!flag) dfs(cur * 10, deep + 1); //下一位枚举0
if(!flag) dfs(cur * 10 + 1, deep + 1); //下一位枚举1
}
int main() {
while(scanf("%llu", &n), n) {
flag = false;
dfs(1, 0); //从1开始搜索
printf("%llu\n", ans);
}
return 0;
}