Golygons UVA - 225 dfs回溯 坐标平移

本文介绍了一种迷宫路径搜索算法,使用递归深度优先搜索方法寻找从起点到终点的所有可能路径。考虑到障碍物和负坐标的问题,通过映射坐标到正数区域,并利用前缀和进行剪枝优化,确保搜索效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一道很简单的题目,但是写的时候莫名奇妙小错误不断很坑爹 用sum前缀和  相减表示最小步数剪枝 同时  可以自交的意思是路线上可以相交,但是不可以停在同一个点 这有点坑爹啊 因为有负坐标 把负的全部映射成正的 大于 (1+n)*n/2的一半的肯定返回不了了,这种障碍点可以直接去掉不用管

#include<bits/stdc++.h>
using namespace std;
const int add=115;
const int maxn=300;
int vis[maxn][maxn];
int mp[maxn][maxn];
int cnt;
int sum[25];
int ans[300];
int dx[]={1,0,0,-1};
int dy[]={0,1,-1,0};
char sign[]="ensw";
int k;
bool check(int x,int y,int bushu,int faxiang){
for(int i=0;i<bushu;i++){
    x+=dx[faxiang];
    y+=dy[faxiang]; //走的过程中如果碰到障碍肯定不行
    if(mp[x][y]==-1)return 0;
}

if(abs(x-add)+abs(y-add)>sum[k]-sum[bushu])return 0; //最大步数都返回不了,剪去
return 1;
}

void dfs(int x,int y,int d,int last){//x y 坐标 d步数 last是上一次的方向



    if(d==k&&x==add&&y==add){

            cnt++;
            for(int i=0;i<d;i++)
        printf("%c",sign[ans[i]]);
    printf("\n");
    return ;
    }



for(int i=0;i<4;i++){
    int tx=x+dx[i]*(d+1); //要加1 从0开始的
    int ty=y+dy[i]*(d+1);
    if(!mp[tx][ty]&&i!=last&&i+last!=3&&!vis[tx][ty]&&check(x,y,(d+1),i)){//不等于上次的方向或者反方向
            ans[d]=i;
            vis[tx][ty]=1;
            dfs(tx,ty,d+1,i);
    vis[tx][ty]=0;

    }
}


}



int main(){
    sum[0] = 0;
	for (int i = 1; i <= 20; i++) sum[i] = sum[i-1] + i; //和数组
int t;
scanf("%d",&t);
    while(t--){
            cnt=0;
            memset(vis,0,sizeof(vis));
            scanf("%d",&k);
            memset(mp,0,sizeof(mp));
            int m;
        scanf("%d",&m);
        for(int i=0;i<m;i++){

            int a,b;
            scanf("%d%d",&a,&b);
            if(abs(a)>maxn||abs(b)>maxn)continue;  //平移add
            mp[a+add][b+add]=-1;
        }
        dfs(add,add,0,-1);//刚开始任意方向直接上一个不会和条件冲突的数就好了我选-1我骄傲
        printf("Found %d golygon(s).\n\n",cnt);
    }


return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值