A 棋盘问题
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
char mp[12][12];
int n, k, ans, b[12], m;
void dfs(int x)
{
if(m == k) {
ans++;
return ;
}
if(x >= n) return ;
for(int i = 0; i < n; i++) {
if(mp[x][i] == '#' && b[i] == 0) { //符合条件可以下棋
b[i] = 1; // 选择下
m++;
dfs(x + 1);
b[i] = 0; // 选择不下
m--;
}
}
dfs(x + 1);
}
int main()
{
while(~scanf("%d %d", &n, &k)) {
if(n == -1 && k == -1) break;
memset(b, 0, sizeof(b));
ans = 0;
m = 0;
for(int i = 0; i < n; i++) scanf("%s", mp[i]);
dfs(0);
printf("%d
", ans);
}
return 0;
}
文章 和这种数字求和问题也是一样的dfs查找。
三维数组跟平面一样。
dr[4][2] 变成了 dr[6][3], 一样查找一样插入就行
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
char mp[50][50][50];
int vis[50][50][50];
int dr[6][3] = {1,0,0, 0,1,0, 0,0,1, -1,0,0, 0,-1,0, 0,0,-1};
int bfs();
int x, y, z, sx, sy,sz, ex, ey, ez;
struct node {
int x, y, z;
int val;
}st, ed;
int main() {
while(~scanf("%d%d%d", &z, &x, &y)) {
memset(vis, 0, sizeof(vis));
if(z == 0 && x == 0 && y == 0) return 0;
for(int i = 0; i < z; i++) {
for(int j = 0; j < x; j++) scanf(" %s", mp[i][j]);
getchar();
}
for(int i = 0; i < z; i++)
for(int j = 0; j < x; j++)
for(int k = 0; k < y; k++) {
if(mp[i][j][k] == 'S') sz = i, sx = j, sy = k;
if(mp[i][j][k] == 'E') ez = i, ex = j, ey = k;
}
int ans = bfs();
if(ans != -1) printf("Escaped in %d minute(s).
", ans);
else printf("Trapped!
");
}
return 0;
}
int bfs() {
queue<node> q;
st.z = sz, st.x = sx, st.y = sy, st.val = 0;
vis[st.z][st.x][st.y] = 1;
q.push(st);
while(!q.empty()) {
st = q.front();
q.pop();
if(st.z == ez && st.x == ex && st.y == ey) return st.val;
for(int i = 0; i < 6; i++) {
ed.z = st.z + dr[i][0];
ed.x = st.x + dr[i][1];
ed.y = st.y + dr[i][2];
if(ed.z>=0&&ed.z<z&&ed.x>=0&&ed.x<x&&ed.y>=0&&ed.y<y&&vis[ed.z][ed.x][ed.y]==0 && (mp[ed.z][ed.x][ed.y]=='.' || mp[ed.z][ed.x][ed.y]=='E')) {
ed.val = st.val + 1;
vis[ed.z][ed.x][ed.y] = 1;
q.push(ed);
}
else continue;
}
}
return -1;
}
题意就是给个n如何变成K,有三种选择+1、-1、*2。 输出最小的变换数。使用bfs。
注意:n k 均小于1e5。 数组一般开MaxN = 1e5 。 但是在 *2 处理时会超过1e5 的数组。所以会报错成Runtime Error。
所以数组开成了2e5 并且还判断了一下 val <= 2 * k。
不过第一次RE后一直在想队列需不需要清空。可能题目不是多组输入。所以没有改也直接过了。
(这个代码写得有点丑,bfs没有单独写出来)
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
const int MaxN = 2e5 + 5;
int vis[MaxN];
struct node {
int val;
int step;
}st, ed;
int main() {
int n, k;
queue<node>q;
while(~scanf("%d%d", &n, &k)) {
st.val = n;
st.step = 0;
vis[n] = 1;
q.push(st);
while(!q.empty()) {
st = q.front();
q.pop();
if(st.val == k) {
printf("%d
", st.step);
continue;
}
for(int i = 0; i < 3; i++) {
if(i == 0) {
ed.val = st.val + 1;
if(vis[ed.val]==0) {
ed.step = st.step + 1;
vis[ed.val] = 1;
q.push(ed);
}
}
else if(i == 1) {
ed.val = st.val - 1;
if(ed.val >= 0 && vis[ed.val] == 0) {
ed.step = st.step + 1;
vis[ed.val] = 1;
q.push(ed);
}
}
else if(i == 2) {
ed.val = st.val * 2;
if(ed.val < 2 * k && vis[ed.val] == 0) {
ed.step = st.step + 1;
vis[ed.val] = 1;
q.push(ed);
}
}
}
}
memset(vis, 0, sizeof(vis));
}
return 0;
}
未完!