这道题是一个让人做完觉得很爽的搜索题,可以用深搜也可以用宽搜。 相对来说,深搜的代码量稍微小一点。 搜索策略就是模拟倒来倒去的过程,并且出现重复的没有意义。
BFS版本: 我是人工写了个队列,这样比STL中的快一点
/*
ID: sdj22251
PROG: calfflac
LANG: C++
*/
#include <iostream>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cmath>
#include <ctime>
#define MAX 2000000000
#define LOCA
#define M 1007
using namespace std;
int a, b, c;
bool can[M];
bool flag[M][M];
struct wwj
{
int x, y, z;
wwj(){}
wwj(int xx, int yy, int zz)
{
x = xx;
y = yy;
z = zz;
}
}q[M * M];
void bfs(int x, int y, int z)
{
int head = 0, tail = 0;
wwj A(x, y, z);
q[tail++] = A;
flag[x][y] = true;
if(A.x == 0) can[A.z] = true;
while(head < tail)
{
A = q[head++];
if(A.x == 0) can[A.z] = true;
if(A.x < a && A.z > 0)
{
if(A.z > a - A.x && !flag[a][A.y]) {wwj B(a, A.y, A.z - a + A.x); flag[B.x][B.y] = true; q[tail++] = B;}
if(A.z <= a - A.x && !flag[A.x + A.z][A.y]) {wwj B(A.x + A.z, A.y, 0); flag[B.x][B.y] = true; q[tail++] = B;}
}
if(A.y < b && A.x > 0)
{
if(A.x > b - A.y && !flag[A.x + A.y - b][b]) {wwj B(A.x + A.y - b, b, A.z); flag[B.x][B.y] = true; q[tail++] = B;}
if(A.x <= b - A.y && !flag[0][A.x + A.y]) {wwj B(0, A.x + A.y, A.z); flag[B.x][B.y] = true; q[tail++] = B;}
}
if(A.z < c && A.y > 0)
{
if(A.y > c - A.z && !flag[A.x][A.y + A.z - c]) {wwj B(A.x, A.y + A.z - c, c); flag[B.x][B.y] = true; q[tail++] = B;}
if(A.y <= c - A.z && !flag[A.x][0]) {wwj B(A.x, 0, A.z + A.y); flag[B.x][B.y] = true; q[tail++] = B;}
}
if(A.x > 0 && A.z < c)
{
if(A.x > c - A.z && !flag[A.x + A.z - c][A.y]) {wwj B(A.x + A.z - c, A.y, c);flag[B.x][B.y] = true; q[tail++] = B;}
if(A.x <= c - A.z && !flag[0][A.y]) {wwj B(0, A.y, A.z + A.x);flag[B.x][B.y] = true; q[tail++] = B;}
}
if(A.y > 0 && A.x < a)
{
if(A.y > a - A.x && !flag[a][A.y + A.x - a]) {wwj B(a, A.y + A.x - a, A.z);flag[B.x][B.y] = true; q[tail++] = B;}
if(A.y <= a - A.x && !flag[A.x + A.y][0]) {wwj B(A.x + A.y, 0, A.z);flag[B.x][B.y] = true; q[tail++] = B;}
}
if(A.z > 0 && A.y < b)
{
if(A.z > b - A.y && !flag[A.x][b]) {wwj B(A.x, b, A.z + A.y - b);flag[B.x][B.y] = true; q[tail++] = B;}
if(A.z <= b - A.y && !flag[A.x][A.y + A.z]) {wwj B(A.x, A.y + A.z, 0);flag[B.x][B.y] = true; q[tail++] = B;}
}
}
}
int main()
{
#ifdef LOCAL
freopen("calfflac.in","r",stdin);
freopen("calfflac.out","w",stdout);
#endif
int i;
scanf("%d%d%d", &a, &b, &c);
bfs(0, 0, c);
for(i = 0; i <= c; i++)
if(can[i])
printf("%d ", i);
printf("\n");
return 0;
}
DFS版本: 可以看到,步骤都很明确
/*
ID: sdj22251
PROG: calfflac
LANG: C++
*/
#include <iostream>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cmath>
#include <ctime>
#define MAX 2000000000
#define LOCA
#define M 1007
using namespace std;
int a, b, c;
bool can[M];
bool flag[M][M];
void dfs(int x, int y, int z)
{
if(flag[x][y]) return;
flag[x][y] = true;
if(x == 0) can[z] = true;
if(x < a && z > 0)
{
if(z > a - x) dfs(a, y, z - a + x);
if(z <= a - x) dfs(x + z, y, 0);
}
if(y < b && x > 0)
{
if(x > b - y) dfs(x + y - b, b, z);
if(x <= b - y) dfs(0, x + y, z);
}
if(z < c && y > 0)
{
if(y > c - z) dfs(x, y + z - c, c);
if(y <= c - z) dfs(x, 0, z + y);
}
if(x > 0 && z < c)
{
if(x > c - z) dfs(x + z - c, y, c);
if(x <= c - z) dfs(0, y, z + x);
}
if(y > 0 && x < a)
{
if(y > a - x) dfs(a, y + x - a, z);
if(y <= a - x) dfs(x + y, 0, z);
}
if(z > 0 && y < b)
{
if(z > b - y) dfs(x, b, z + y - b);
if(z <= b - y) dfs(x, y + z, 0);
}
}
int main()
{
#ifdef LOCAL
freopen("calfflac.in","r",stdin);
freopen("calfflac.out","w",stdout);
#endif
int i;
scanf("%d%d%d", &a, &b, &c);
dfs(0, 0, c);
for(i = 0; i <= c; i++)
if(can[i])
printf("%d ", i);
printf("\n");
return 0;
}