题目:poj 2488 A Knight's Journey
题意:
给一个m*n的棋盘,马走日,给出一条字典序最小的马的路线来走完整个棋盘?
分析:
如果能走完棋盘,那么从(1,1)点dfs即可,因为他能走完整个棋盘嘛,总有一步会经过(1,1),所以从(1,1)出发就能到其他所有点。
为了保证字典序,在枚举方向时顺序要保证x轴优先,然后y轴。
#include
#include
#include
#include
#include
using namespace std;
const int N=33;
typedef pairpii;
vectorans;
int dx[][2]={{-2,-1},{-2,1},{-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1}};
int n,m;
bool vis[N][N];
bool dfs(int x,int y,int step)
{
if(step==n*m)return 1;
for(int i=0;i<8;i++){
int xx=dx[i][0]+x;
int yy=dx[i][1]+y;
if(xx<1||yy<1||xx>n||yy>m||vis[xx][yy])continue;
vis[xx][yy]=1;
ans.push_back(make_pair(xx,yy));
if(dfs(xx,yy,step+1)) return 1;
vis[xx][yy]=0;
ans.pop_back();
}
return 0;
}
int main()
{
int T;scanf("%d",&T);
for(int cas=1;cas<=T;cas++){
ans.clear();
scanf("%d%d",&m,&n);
ans.push_back(make_pair(1,1));
memset(vis,0,sizeof(vis));
vis[1][1]=1;
printf("Scenario #%d:\n",cas);
if(dfs(1,1,1)){
for(int i=0;i
题目:poj 3009
题意:
滚小球,小球刚开始在起点S,每次可以往四个方向扔出,扔出后小球一直滚动,直到碰到砖块(砖块碰到后消失)或者到达终点E。问小球到E的最短路?
分析:
虽然是到类似于最短路的题目,但是似乎bfs是不行的,因为每次球发生碰撞后会改变地图,有可能出现更优解!所以要dfs找出所有的可能解(所以数据范围才小),但是要剪枝,不然会超时。
#include
using namespace std;
const int INF=0x3f3f3f3f;
const int N=22;
int g[N][N];
int w,h,sx,sy;
int dx[][2]={{-1,0},{1,0},{0,-1},{0,1}};
int ans=INF;
void dfs(int x,int y,int step)
{
if(step>=10||step>=ans)return; //剪枝
for(int i=0;i<4;i++){
int xx=dx[i][0]+x;
int yy=dx[i][1]+y;
if(g[xx][yy]==1)continue;
while(xx>=0&&xx=0&&yy
题目:poj 1321
题意:
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。
每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n
分析:
要找所有方案,显然是要dfs找出所有可能解。因为放了的棋子不能在同一行或者同一列,很容易想到开两个数组标记一下有棋子的行和列,但是这似乎还不能解决这个问题,因为可能出现重复(比如这种方案是AB两点,另一种方案是BA两点),为了防止重复,可以逐行枚举,这样就不会出现重复的情况了。
#include
#include
using namespace std;
const int N=10;
int n,k;
bool visy[N],g[N][N];
char s[N];
int ans;
void dfs(int row,int step)
{
if(step==k){
ans++;return;
}
for(int i=row;i
题目:poj 2251
题意:
给出一个三维的图,求S到E的最短路
分析:
裸的bfs
#include
#include
#include
using namespace std;
#define mp make_pair
const int N=33;
typedef pairpii;
typedef pairstate; //步数,层,行,列,可能写个struct清晰点QAQ
char g[N][N][N];
bool vis[N][N][N];
int C,L,R,sl,sc,sr; //层数,行数,列数,开始的层行列
int d[][3]={{0,0,-1},{0,0,1},{0,-1,0},{0,1,0},{-1,0,0},{1,0,0}};
int bfs()
{
queueq;
q.push(mp(mp(0,sl),mp(sr,sc)));
memset(vis,0,sizeof(vis));
vis[sl][sr][sc]=1;
while(!q.empty()){
state t=q.front();q.pop();
int step=t.first.first,l=t.first.second,r=t.second.first,c=t.second.second;
for(int i=0;i<6;i++){
int tl=l+d[i][0],tr=r+d[i][1],tc=c+d[i][2];
if(tl<0||tl==L||tr<0||tr==R||tc<0||tc==C||vis[tl][tr][tc]||g[tl][tr][tc]=='#')continue;
if(g[tl][tr][tc]=='E')return step+1;
vis[tl][tr][tc]=1;
q.push(mp(mp(step+1,tl),mp(tr,tc)));
}
}
return -1;
}
int main()
{
while(~scanf("%d%d%d",&L,&R,&C)&&(L+R+C)){
for(int l=0;l