zoukankan      html  css  js  c++  java
  • POJ2488&&3083&&3009&&1321&&2251&&2049

    刷完了大力数据结构(水比数据结构专题)后又开始搞无脑搜索专题

    这次的标签是DFS(这TM的到现在了谁还不会)

    2488

    跳马问题:给出一个棋盘,让你求一个方案使一匹马能花最短的时间不重复不遗漏地跳完整个棋盘(并要求字典序最小)

    很显然,如果可以遍历,那么从任何一个点开始都可以遍历整个棋盘。因此选字典序最小的A1开始遍历,然后找一种字典序最小的搜索顺序DFS即可

    CODE

    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=30,fx[8]={-1,1,-2,2,-2,2,-1,1},fy[8]={-2,-2,-1,-1,1,1,2,2};
    struct data
    {
    	int x,y;
    }next[N][N];
    int t,n,m;
    bool vis[N][N],flag;
    inline char tc(void)
    {
    	static char fl[100000],*A=fl,*B=fl;
    	return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
    }
    inline void read(int &x)
    {
    	x=0; char ch=tc();
    	while (ch<'0'||ch>'9') ch=tc();
    	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
    }
    inline void print(void)
    {
    	int x=1,y=1; putchar(y+'A'-1); putchar(x+'0');
    	while (next[x][y].x!=-1&&next[x][y].y!=-1)
    	{
    		int xx=next[x][y].x,yy=next[x][y].y;
    		putchar(yy+'A'-1); putchar(xx+'0');
    		x=xx; y=yy;
    	}
    	putchar('
    '); 
    }
    inline void DFS(int x,int y,int tot)
    {
    	if (flag) return;
    	if (tot==n*m) { flag=1; print(); return; }
    	for (register int i=0;i<8;++i)
    	{
    		int xx=x+fx[i],yy=y+fy[i];
    		if (xx>0&&xx<=n&&yy>0&&yy<=m&&!vis[xx][yy])
    		{
    			vis[xx][yy]=1;
    			next[x][y].x=xx; next[x][y].y=yy;
    			DFS(xx,yy,tot+1);
    			vis[xx][yy]=0;
    			next[x][y].x=next[x][y].y=-1;
    		}
    	}
    }
    int main()
    {
    	register int i;
    	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
    	for (read(t),i=1;i<=t;++i)
    	{
    		read(n); read(m);
    		memset(vis,0,sizeof(vis));
    		memset(next,-1,sizeof(next));
    		printf("Scenario #%d:
    ",i);
    		flag=0; vis[1][1]=1; DFS(1,1,1);
    		if (!flag) puts("impossible"); putchar('
    ');
    	}
    	return 0;
    }
    

    3083

    之前已经做过,详见

    3009

    打冰球,冰球打到障碍物会在它前面停下并可以重新选择方向。如果击打了冰球那么它就会一直向一个方向冲过去知道它碰到了障碍或到达中点。求最小击打次数。

    因为如果超过10次就直接算做失败,因此直暴力DFS即可

    CODE

    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=25;
    int map[N][N],n,m,s_x,s_y,t_x,t_y,ans;
    inline char tc(void)
    {
    	static char fl[100000],*A=fl,*B=fl;
    	return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
    }
    inline void read(int &x)
    {
    	x=0; char ch=tc();
    	while (ch<'0'||ch>'9') ch=tc();
    	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
    }
    inline void write(int x)
    {
    	if (x<0) putchar('-'),x=-x;
    	if (x/10) write(x/10);
    	putchar(x%10+'0');
    }
    inline int min(int a,int b)
    {
    	return a<b?a:b;
    }
    inline void DFS(int x,int y,int tot)
    {
    	register int i;
    	for (i=x-1;i>=1;--i)
    	if (map[i][y]==3)
    	{
    		if (tot+1<=10) ans=min(ans,tot+1); return; 
    	} else if (map[i][y]==1)
    	{
    		if (x-i==1) break;
    		map[i][y]=0;
    		if (tot+1<=10) DFS(i+1,y,tot+1);
    		map[i][y]=1;
    		break;
    	}
    	for (i=x+1;i<=n;++i)
    	if (map[i][y]==3)
    	{
    		if (tot+1<=10) ans=min(ans,tot+1); return; 
    	} else if (map[i][y]==1)
    	{
    		if (i-x==1) break;
    		map[i][y]=0;
    		if (tot+1<=10) DFS(i-1,y,tot+1);
    		map[i][y]=1;
    		break;
    	}
    	for (i=y-1;i>=1;--i)
    	if (map[x][i]==3)
    	{
    		if (tot+1<=10) ans=min(ans,tot+1); return; 
    	} else if (map[x][i]==1)
    	{
    		if (y-i==1) break;
    		map[x][i]=0;
    		if (tot+1<=10) DFS(x,i+1,tot+1);
    		map[x][i]=1;
    		break;
    	}
    	for (i=y+1;i<=m;++i)
    	if (map[x][i]==3)
    	{
    		if (tot+1<=10) ans=min(ans,tot+1); return; 
    	} else if (map[x][i]==1)
    	{
    		if (i-y==1) break;
    		map[x][i]=0;
    		if (tot+1<=10) DFS(x,i-1,tot+1);
    		map[x][i]=1;
    		break;
    	}
    }
    int main()
    {
    	register int i,j;
    	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
    	read(m); read(n); 
    	while (m&&n)
    	{
    		for (i=1;i<=n;++i)
    		for (j=1;j<=m;++j)
    		{
    			read(map[i][j]);
    			if (map[i][j]==2) s_x=i,s_y=j;
    			if (map[i][j]==3) t_x=i,t_y=j;
    		}
    		ans=1e9; DFS(s_x,s_y,0);
    		write(ans!=1e9?ans:-1); putchar('
    ');
    		read(m); read(n);
    	}
    	return 0;
    }
    

    1321

    对于这道难得的中文题目我都喜极而泣了

    就注意一下‘#’才是放旗子的地方

    CODE

    #include<iostream>
    using namespace std;
    const int N=10;
    char map[N][N];
    bool l[N];
    int n,k,ans;
    inline void DFS(int now,int tot)
    {
    	if (tot==k) { ++ans; return; }
    	if (now>n) return;
    	for (register int i=1;i<=n;++i)
    	if (map[now][i]!='.'&&!l[i]) l[i]=1,DFS(now+1,tot+1),l[i]=0;
    	DFS(now+1,tot);
    }
    int main()
    {
    	register int i,j;
    	std::ios::sync_with_stdio(false);
    	cin>>n>>k;
    	while (n!=-1&&k!=-1)
    	{
    		for (i=1;i<=n;++i)
    		for (j=1;j<=n;++j)
    		cin>>map[i][j];
    		ans=0; DFS(1,0);
    		cout<<ans<<endl;
    		cin>>n>>k;
    	}
    	return 0;
    }
    

    2251

    三维迷宫求最短路径

    这其实是用BFS的......设六个方向的数组即可

    CODE

    #include<iostream>
    #include<cstring>
    using namespace std;
    const int N=35,fx[6]={0,1,0,-1,0,0},fy[6]={1,0,-1,0,0,0},fz[6]={0,0,0,0,1,-1};
    char map[N][N][N];
    int q[N*N*N][3],step[N*N*N],n,m,d,s_x,s_y,s_z,t_x,t_y,t_z;
    bool vis[N][N][N];
    inline int BFS(int z,int x,int y)
    {
    	int head=0,tail=1;
    	memset(vis,0,sizeof(vis));
    	step[1]=0; q[1][0]=z; q[1][1]=x; q[1][2]=y; vis[z][x][y]=1;
    	while (head<tail)
    	{
    		z=q[++head][0]; x=q[head][1]; y=q[head][2];
    		if (z==t_z&&x==t_x&&y==t_y) return step[head];
    		for (register int i=0;i<8;++i)
    		{
    			int zz=z+fz[i],xx=x+fx[i],yy=y+fy[i];
    			if (zz>0&&zz<=d&&xx>0&&xx<=n&&yy>0&&yy<=m&&map[zz][xx][yy]!='#'&&!vis[zz][xx][yy])
    			{
    				q[++tail][0]=zz; q[tail][1]=xx; q[tail][2]=yy;
    				step[tail]=step[head]+1; vis[zz][xx][yy]=1;
    			}
    		}
    	}
    	return -1;
    }
    int main()
    {
    	register int i,j,k;
    	std::ios::sync_with_stdio(false);
    	cin>>d>>n>>m;
    	while (d&&n&&m)
    	{
    		for (i=1;i<=d;++i)
    		for (j=1;j<=n;++j)
    		for (k=1;k<=m;++k)
    		{
    			cin>>map[i][j][k];
    			if (map[i][j][k]=='S') s_z=i,s_x=j,s_y=k;
    			if (map[i][j][k]=='E') t_z=i,t_x=j,t_y=k;
    		}
    		int ans=BFS(s_z,s_x,s_y);
    		if (ans!=-1) cout<<"Escaped in "<<ans<<" minute(s)."<<endl; else cout<<"Trapped!"<<endl;
    		cin>>d>>n>>m;
    	}
    	return 0;
    }
    

    2049

    也做过了,看这里

  • 相关阅读:
    python 配置环境变量无效问题
    vscode 快捷隐藏node_modules目录
    qs 格式化
    webstorm vue 格式化 script 最外层缩进问题
    electron-vue static静态目录
    解决VS Code安装golang相关插件失败问题
    linux云机器快速部署备忘录
    添加用户(过火绒)
    hvv面试题
    comsvcs.dll转储lsass(过360卫士&火绒)
  • 原文地址:https://www.cnblogs.com/cjjsb/p/8869723.html
Copyright © 2011-2022 走看看