红皇后的旅行(贪心出奇迹)——宇&&小猪周周

redqueen

我是贪心之***:

题目描述

       给定一个n*n的棋盘,行和列标号为0,1,2,….,n-1。在棋盘的(i_start,j_start)位置上有一位红皇后,每次红皇后可以往六个方向走,如图所示:

       现在红皇后想去(i_end,j_end)点,求最短距离,并且输出一条路径。

       显然最短路径有无穷条,请按照以下顺序来搜索:UL, UR, R, LR, LL, L

       如果无解,输出Impossible

格式

       输入第一行一个数n,第二行四个数,i_start,j_start,i_end,j_end。

       输出第一行一个数,最小步数,第二行输出方案。

范围

      

       首先想到的是bfs,如下:

#include<bits/stdc++.h>
using namespace std;
int n,is,js,ie,je;
int bj[210][210],ami=20010;
string a[20010];

int dfs(int x,int y,int bs,string zf,bool &fl)
{
    if(x==ie && y==je)
    {
        a[bs]=zf;
        fl=true;
        return bs;
    }
    if(bs>=ami) return 20010;
    if(bj[x][y]) return 20010;
    bj[x][y]=1;
    bool f=false,ff=false;
    int s=dfs(x,y-2,bs+1,"L",f);
    string z;
    if(f) z="L",ff=true;
    f=false;
    s=min(s,dfs(x+2,y-1,bs+1,"LL",f));
    if(f) z="LL",ff=true;
    f=false;
    s=min(s,dfs(x+2,y+1,bs+1,"LR",f));
    if(f) z="LR",ff=true;
    f=false;
    s=min(s,dfs(x,y+2,bs+1,"R",f));
    if(f) z="R",ff=true;
    f=false;
    s=min(s,dfs(x-2,y+1,bs+1,"UR",f));
    if(f) z="UR",ff=true;
    f=false;
    s=min(s,dfs(x-2,y-1,bs+1,"UL",f));
    if(f) z="UL",ff=true;
    if(ff) a[bs]=z;
    fl=ff;
    return s;
}

int why()
{
    bool f=false;
    int ss=dfs(is,js,0,0,f);
    if(ss==20010) printf("Impossible\n");
    else printf("%d\n",ss);
    for(int i=1;i<ss;i++) cout<<a[i]+" ";
    cout<<a[ss]<<endl;
    fclose(stdin);
    fclose(stdout);
    return 0;
}

int main()
{
//    freopen("redqueen.in","r",stdin);
//    freopen("redqueen.out","w",stdout);
    scanf("%d",&n);
    scanf("%d%d%d%d",&is,&js,&ie,&je);
    
    return why();
}

       然后这个程序出现了未知错误,崩了:

       搞了半天不知为什么,所以就先躺了一会儿,随后I think I have to重操旧业(贪心),然后写了一个差一丢丢的贪心(不是打表!!!),反正目标在那个方向就往那边跑,跑一步盘一次可能性,那个漏洞就是优先度:

#include<bits/stdc++.h>
using namespace std;
int n,is,js,ie,je;
int x,y,ans=0;
string a[40010];

bool No(int x,int y)
{
    int i=ie,j=je;
    if(i==x-2 && j==y-2) return true;
    if(i==x-2 && j==y) return true;
    if(i==x-2 && j==y+2) return true;
    if(i==x-1 && j==y-2) return true;
    if(i==x-1 && j==y-1) return true;
    if(i==x-1 && j==y) return true;
    if(i==x-1 && j==y+1) return true;
    if(i==x-1 && j==y+2) return true;
    if(i==x && j==y-1) return true;
    if(i==x && j==y+1) return true;
    if(i==x+1 && j==y-2) return true;
    if(i==x+1 && j==y-1) return true;
    if(i==x+1 && j==y) return true;
    if(i==x+1 && j==y+1) return true;
    if(i==x+1 && j==y+2) return true;
    if(i==x+2 && j==y-2) return true;
    if(i==x+2 && j==y) return true;
    if(i==x+2 && j==y+2) return true;
    return false;
}

int why()
{
    x=is,y=js;
    int i=ie,j=je;
    while(x!=i || y!=j)
    {
        if(No(x,y))
        {
            printf("Impossible\n");
            fclose(stdin);
            fclose(stdout);
            return 0;
        }
        if(x>i && y>j) a[++ans]="UL",x-=2,y--;
        else if(x>i && y<j) a[++ans]="UR",x-=2,y++;
        else if(x==i && y<j) a[++ans]="R",y+=2;
        else if(x<i && y<j) a[++ans]="LR",x+=2,y++;
        else if(x<i && y>j) a[++ans]="LL",x+=2,y--;
        else if(x==i && y>j) a[++ans]="L",y-=2;
        else if(x>i && y==j) a[++ans]="UL",x-=2,y--;
        else if(x<i && y==j) a[++ans]="LR",x+=2,y++;
    }
    printf("%d\n",ans);
    for(int i=1;i<ans;i++) cout<<a[i]<<" ";
    cout<<a[ans]<<endl;
    fclose(stdin);
    fclose(stdout);
    return 0;
}

int main()
{
    freopen("redqueen.in","r",stdin);
    freopen("redqueen.out","w",stdout);
    scanf("%d",&n);
    scanf("%d%d%d%d",&is,&js,&ie,&je);
    return why();
}
 

       问题就出在上,因为题目规定了优先级,这向右下和向左下移动的玩意就萎了,改成如此神奇的特判就好了,上面那个“No”函数是用来判“Impossible”的,再强调三遍:这不是打表!这不是打表!这不是打表!。

       所以我用着个代码A掉之后,被***了一顿,又被人提起了那个 贪心水DP 的***经历。

这是一个DP专练可以贪掉的大佬。。。(还AK了。。。)

所以大家不要奇怪。。。

好的,就让我来你搞一个BFS吧。。。

其实这真的是一个很裸的BFS(可惜我考试写了DFS还炸了。。。)

唉(惆怅)。。。

因为在一个图上要你找最短路的搜索差不多都是BFS。。。

为什么呢???

因为!显然!易证!(套路。。。)(老刘说的。。。)

好的,既然都是BFS了,就不多说了

上code

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int dy[8]={0,-1,1,2,1,-1,-2},dx[8]={0,-2,-2,0,2,2,0};
const string c[8]={"  ","UL ","UR ","R ","LR ","LL ","L "};
struct edge
{
	int x,y,z;
}f[300][300];
struct edge1
{
	int x,y,z;
}q[100010],s,e;
int h=1,t,n;
bool p[220][220];
void find(int x,int y)
{
	if(f[x][y].x==s.x&&f[x][y].y==s.y)
	{
		cout<<c[f[x][y].z];
	}
	else 
	{
		find(f[x][y].x,f[x][y].y);
		cout<<c[f[x][y].z];
	}
}
inline ll read()
{
	register int K=0,F=1;register char C=getchar() ;
	while(C<'0'or C>'9')F=C=='-'?-1:1,C=getchar() ;
	while(C<='9'and C>='0')K=(K<<1)+(K<<3)+C-'0',C=getchar() ;
	return F*K;
}
int main()
{
	freopen("redqueen.in","r",stdin);
	freopen("redqueen.out","w",stdout);
	n=read();s.x=read();s.y=read();e.x=read();e.y=read();
	q[++t]=s;p[s.x][s.y]=1;
	while(h<=t)
	{
		int x=q[h].x,y=q[h].y,z=q[h++].z;
		for(int i=1;i<=6;i++)
		{
			int x1=x+dx[i],y1=y+dy[i];
			if(x1<0||x1>n-1||y1<0||y1>n-1)continue;
			if(!p[x1][y1])
			{
				q[++t].x=x1,q[t].y=y1,q[t].z=z+1;
				f[x1][y1].x=x,f[x1][y1].y=y,f[x1][y1].z=i;
				p[x1][y1]=1;
				if(x1==e.x&&y1==e.y)
				{
					cout<<z+1<<endl;
					int ax=x1,ay=y1;
					find(ax,ay);
					return 0;
				}
				
			}
		}
	}
	printf("Impossible");
	return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值