A 棋盘问题
我就是一个智障,总是把变量弄错,导致浪费了很多时间
用简单的回溯法,就可以暴力破解
我的代码:
#include<cstdio>
using namespace std;
const int MAXN = 9;
bool col[MAXN];
char qipan[MAXN][MAXN];
int n, maxk;
int ans = 0;
bool read () {
scanf("%d %d", &n, &maxk);
if (n == -1) return false;
ans = 0;
for (int i = 0; i < n; i++) {
scanf("%s", qipan[i]);
}
return true;
}
void dfs (int i, int cur) {
if (cur == maxk) {
ans++;
return;
}
for (int k = i; k <= n-maxk+cur; k++) {
for (int j = 0; j < n; j++) {
if (!col[j] && qipan[k][j] == '#') {
col[j] = true;
dfs(k+1, cur+1);
col[j] = false;
}
}
}
}
int main () {
while (read()) {
dfs(0, 0);
printf("%d\n", ans);
}
}
B Dungeon Master
使用bfs就可以了
我的代码:
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int MAXN = 32;
const int MAXD = 6;
const int di[] = {0, 0, 0, 0, 1, -1}; // i是控制上下
const int dj[] = {1, -1, 0, 0, 0, 0}; // j是控制前后
const int dk[] = {0, 0, 1, -1, 0, 0}; // k是控制左右
char migong[MAXN][MAXN][MAXN];
int d[MAXN][MAXN][MAXN], L, R, C, si, sj, sk;
bool read () {
scanf("%d %d %d", &L, &R, &C);
if (L == 0) return 0;
for (int i = 0; i < L; i++) {
for (int j = 0; j < R; j++) {
scanf("%s", migong[i][j]);
for (int k = 0; k < C; k++) {
if (migong[i][j][k] == 'S') {
si = i; sj = j; sk = k;
}
}
}
}
memset(d, -1, sizeof(d));
return true;
}
bool inside (int i, int j, int k) {
return i >= 0 && j >= 0 && k >= 0 && i < L && j < R && k < C;
}
int bfs () {
queue<int> qi, qj, qk;
qi.push(si); qj.push(sj); qk.push(sk);
d[si][sj][sk] = 0;
while (!qi.empty()) {
int i = qi.front(), j = qj.front(), k = qk.front();
qi.pop(); qj.pop(); qk.pop();
for (int l = 0; l < MAXD; l++) {
int ni = i+di[l], nj = j+dj[l], nk = k+dk[l];
if (inside(ni, nj, nk) && d[ni][nj][nk] == -1) {
if (migong[ni][nj][nk] == '.') {
d[ni][nj][nk] = d[i][j][k]+1;
qi.push(ni); qj.push(nj); qk.push(nk);
} else if (migong[ni][nj][nk] == 'E') {
return d[i][j][k]+1;
}
}
}
}
return 0;
}
int main () {
while (read()) {
int ans = bfs();
if (ans == 0) {
printf("Trapped!\n");
} else {
printf("Escaped in %d minute(s).\n", ans);
}
}
}
C Find The Multiple
这道题,一开始是没有什么思路的,看了别人的解答过程,才有的思路,主要是涉及了关于数学的运算
手动模拟一下除法的过程,就会发现:上一位的除法剩下的余数乘以10,会进入下一位的除法运算的运算
我的代码:
#include<cstdio>
using namespace std;
const int MAXN = 100;
int p[MAXN], len, n;
bool dfs (int cur, int r) {
if (cur < MAXN) {
p[cur] = 1;
if ((r*10+1)%n == 0) {
len = cur+1;
return true;
}
if (dfs(cur+1, (r*10+1)%n)) {
return true;
}
p[cur] = 0;
if ((r*10)%n == 0) {
len = cur+1;
return true;
}
if (dfs(cur+1, (r*10)%n)) {
return true;
}
}
return false;
}
int main () {
while (scanf("%d", &n) && n != 0) {
dfs(0, 0);
for (int i = 0; i < len; i++) {
printf("%d", p[i]);
}
printf("\n");
}
}
D Prime Path
先把所有素数都存储下来,然后再用bfs寻找最短路径
我的代码:
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
const int MAXN = 10;
bool prime[MAXN][MAXN][MAXN][MAXN];
int d[MAXN][MAXN][MAXN][MAXN], start[4], goal[4];
void calPrime () {
int index[4];
for (int i = 9999; i >= 1000; i--) {
bool ok = true;
if (i == 8179) {
int k = 0;
}
for (int j = sqrt(i); j > 1; j--) {
if (i%j == 0) {
ok = false;
break;
}
}
if (ok) {
for (int j = 3, num = i; j >= 0; j--, num = num/10) {
index[j] = num%10;
}
prime[index[0]][index[1]][index[2]][index[3]] = true;
}
}
}
int bfs () {
queue<int> q0, q1, q2, q3;
int num[4];
q0.push(start[0]); q1.push(start[1]); q2.push(start[2]); q3.push(start[3]);
d[start[0]][start[1]][start[2]][start[3]] = 0;
while (!q0.empty()) {
num[0] = q0.front(), num[1] = q1.front(), num[2] = q2.front(), num[3] = q3.front();
q0.pop(); q1.pop(); q2.pop(); q3.pop();
int depth = d[num[0]][num[1]][num[2]][num[3]];
if (num[0] == goal[0] && num[1] == goal[1] && num[2] == goal[2] && num[3] == goal[3]) return depth;
for (int i = 0; i < 4; i++) {
int flag = num[i];
for (num[i]; num[i] >= 0; num[i]--) {
if (prime[num[0]][num[1]][num[2]][num[3]] && d[num[0]][num[1]][num[2]][num[3]] == -1) {
d[num[0]][num[1]][num[2]][num[3]] = depth+1;
q0.push(num[0]); q1.push(num[1]); q2.push(num[2]); q3.push(num[3]);
}
}
num[i] = flag;
for (num[i]; num[i] < 10; num[i]++) {
if (prime[num[0]][num[1]][num[2]][num[3]] && d[num[0]][num[1]][num[2]][num[3]] == -1) {
d[num[0]][num[1]][num[2]][num[3]] = depth+1;
q0.push(num[0]); q1.push(num[1]); q2.push(num[2]); q3.push(num[3]);
}
}
num[i] = flag;
}
}
return -1;
}
int main () {
calPrime();
int T;
scanf("%d", &T);
while (T--) {
int a, b;
scanf("%d %d", &a, &b);
memset(d, -1, sizeof(d));
for (int i = 3, num1 = a, num2 = b; i >= 0; i--, num1 = num1/10, num2 = num2/10) {
start[i] = num1%10;
goal[i] = num2%10;
}
int ans = bfs();
printf("%d\n", ans);
}
return 0;
}
E Shuffle’m Up
比起简单搜索更像是模拟题,用set记录那些遍历过的数据,如果产生循环,则结果是不可能到达的,输出-1
我的代码:
#include<iostream>
#include<string>
#include<set>
using namespace std;
const int MAXC = 200;
int C;
string p1, p2, p, ans;
set<string> cache;
int solve () {
for (int cnt = 1; ; cnt++) {
for (int i = 0; i < C; i++) { // 把p2放在下面
p[i*2+1] = p1[i];
p[i*2] = p2[i];
}
if (ans == p) return cnt;
if (cache.count(p)) return -1;
cache.insert(p);
p1 = p.substr(0, C);
p2 = p.substr(C, C);
}
}
int main () {
int T;
cin >> T;
for (int t = 1; t <= T; t++) {
cin >> C;
cache.clear();
getline(cin, p1);
getline(cin, p1);
getline(cin, p2);
p = p1+p2;
getline(cin, ans);
int ans = solve();
cout << t << " " << ans << endl;
}
return 0;
}