这道题要剪枝,不然会超时,还有就是每次参加过的城市下次不能再参观,不然会WA。
对于障碍物的坐标我用了两种方法,第一种就是直接用STL里面的set,对于判断是否访问过直接用的count,用时960ms;当我把集合换成数组,200ms通过。
用set的AC代码:

#include<cstring>
#include<cstdio>
#include<cmath>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=300;
int dx[]={1,0,0,-1,5};
int dy[]={0,1,-1,0,5}; //east,north,south,west
char dir[]="ensw";
int vis[maxn][maxn];
int n,cnt;
struct node{int x,y;node(int x=0,int y=0):x(x),y(y){}bool operator < (const node &p) const{return x>p.x||(x==p.x&&y>p.y);}
};
set<node>u;void dfs(int *a,int cur,int d,node pos){if(cur==n&&pos.x==150&&pos.y==150){cnt++;for(int i=0;i<n;++i) printf("%c",dir[a[i]]);printf("\n");return;}if(cur>=n) return;if((abs(pos.x-150)+abs(pos.y-150))>((n-cur)*(n+cur+1)/2)) return; //cutfor(int i=0;i<4;++i){if(dx[i]==dx[d]||dy[i]==dy[d]) continue;int newx=pos.x+(cur+1)*dx[i],newy=pos.y+(cur+1)*dy[i];if(vis[newx][newy]) continue; //已经旅游过int flag=0,c,p;if(newx==pos.x){c=min(newy,pos.y),p=max(newy,pos.y);for(int k=c;k<=p;++k){node newc(newx,k);if(u.count(newc)) {flag=1;break;}}}else if(newy==pos.y){c=min(newx,pos.x),p=max(newx,pos.x);for(int k=c;k<=p;++k){node newc(k,newy);if(u.count(newc)) {flag=1;break;}}}if(flag) continue;a[cur]=i;vis[newx][newy]=1;dfs(a,cur+1,i,node(newx,newy));vis[newx][newy]=0;}
}int main(){int T;scanf("%d",&T);while(T--){memset(vis,0,sizeof(vis));int k;scanf("%d%d",&n,&k);int x,y;for(int i=0;i<k;++i){scanf("%d%d",&x,&y);u.insert(node(x+150,y+150)); //障碍物坐标保存}cnt=0;int a[25];dfs(a,0,4,node(150,150));printf("Found %d golygon(s).\n\n",cnt);u.clear();}return 0;
}

用数组的AC代码:

#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=300;
int dx[]={1,0,0,-1,5};
int dy[]={0,1,-1,0,5}; //east,north,south,west
char dir[]="ensw";
int vis[maxn][maxn],def[maxn][maxn];
int n,cnt;
struct node{int x,y;node(int x=0,int y=0):x(x),y(y){}bool operator < (const node &p) const{return x>p.x||(x==p.x&&y>p.y);}
};void dfs(int *a,int cur,int d,node pos){if(cur==n&&pos.x==150&&pos.y==150){cnt++;for(int i=0;i<n;++i) printf("%c",dir[a[i]]);printf("\n");return;}if(cur>=n) return;if((abs(pos.x-150)+abs(pos.y-150))>((n-cur)*(n+cur+1)/2)) return; //cutfor(int i=0;i<4;++i){if(dx[i]==dx[d]||dy[i]==dy[d]) continue;int newx=pos.x+(cur+1)*dx[i],newy=pos.y+(cur+1)*dy[i];if(vis[newx][newy]) continue; //已经旅游过int flag=0,c,p;if(newx==pos.x){c=min(newy,pos.y),p=max(newy,pos.y);for(int k=c;k<=p;++k){node newc(newx,k);if(def[newx][k]) {flag=1;break;}}}else if(newy==pos.y){c=min(newx,pos.x),p=max(newx,pos.x);for(int k=c;k<=p;++k){node newc(k,newy);if(def[k][newy]) {flag=1;break;}}}if(flag) continue;a[cur]=i;vis[newx][newy]=1;dfs(a,cur+1,i,node(newx,newy));vis[newx][newy]=0;}
}int main(){int T;scanf("%d",&T);while(T--){memset(vis,0,sizeof(vis));memset(def,0,sizeof(def));int k;scanf("%d%d",&n,&k);int x,y;for(int i=0;i<k;++i){scanf("%d%d",&x,&y);def[x+150][y+150]=1;}cnt=0;int a[25];dfs(a,0,4,node(150,150));printf("Found %d golygon(s).\n\n",cnt);}return 0;
}

如有不当之处欢迎指出!

转载于:https://www.cnblogs.com/flyawayl/p/8305565.html

uva225 回溯剪枝相关推荐

  1. 回溯 剪枝 之跳马问题

    回溯 剪枝 之跳马问题 原创声明 // // Created by Chenglong Shi on 2021/11/19. // Only can use to study // Once foun ...

  2. [Leetcode][第40题][JAVA][数组总和2][回溯][剪枝]

    [问题描述][中等] [解答思路] 1. 减法 import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Ar ...

  3. LeetCode 1681. 最小不兼容性(回溯+剪枝)

    文章目录 1. 题目 2. 解题 1. 题目 给你一个整数数组 nums​​​ 和一个整数 k .你需要将这个数组划分到 k 个相同大小的子集中,使得同一个子集里面没有两个相同的元素. 一个子集的 不 ...

  4. LeetCode 996. 正方形数组的数目(回溯+剪枝)

    文章目录 1. 题目 2. 解题 1. 题目 给定一个非负整数数组 A,如果该数组每对相邻元素之和是一个完全平方数,则称这一数组为正方形数组. 返回 A 的正方形排列的数目.两个排列 A1 和 A2 ...

  5. LeetCode 1601. 最多可达成的换楼请求数目(回溯+剪枝)

    文章目录 1. 题目 2. 解题 1. 题目 我们有 n 栋楼,编号从 0 到 n - 1 .每栋楼有若干员工.由于现在是换楼的季节,部分员工想要换一栋楼居住. 给你一个数组 requests ,其中 ...

  6. 剑指Offer - 面试题38. 字符串的排列(全排列,排序,回溯+剪枝)

    1. 题目 输入一个字符串,打印出该字符串中字符的所有排列. 你可以以任意顺序返回这个字符串数组,但里面不能有重复元素. 示例: 输入:s = "abc" 输出:["ab ...

  7. leetcode(力扣) 39. 组合总和(回溯 剪枝)

    文章目录 题目描述 思路分析 完整代码 剪枝: 完整代码 题目描述 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为 ...

  8. POJ1416 Shredding Company ACM解题报告(DFS回溯+剪枝)

    本渣渣明天C语言考试,今天有点亢奋,又来了一题,这题感觉比前一题难多了,不仅是字符串转化为数字,即使看了百度提醒的搜索树,还是参考了一些百度的代码.感觉道阻且长,我仍需努力.下面是题目翻译: 公司现在 ...

  9. Leetcode47全排列II(回溯+剪枝)

    给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列. /*** @param {number[]} nums* @return {number[][]}*/ var perm ...

最新文章

  1. Lightroom学习随笔
  2. [禅悟人生]每个人都可以获得自己的精彩
  3. 利用WinRAR命令行压缩文件或文件夹
  4. 深入到系统组件是否白盒测试_白盒测试
  5. 能用c语言编写图形界面吗,「分享」C语言如何编写图形界面
  6. [译]ASP.NET Core 2.0 带初始参数的中间件
  7. 对象拷贝的工具类DeepBeanUtils
  8. ArrayList clone()– ArrayList深拷贝和浅拷贝
  9. Oracle创建表语句(Create table)语法详解及示例
  10. Spring Boot学习总结(11)——SpringBoot的Starter依赖包及作用
  11. signature=995eb8e443ef674d51fa76dabc7ac89c,我國7-8歲學童動作協調能力之初探
  12. Android开发之异步消息处理机制AsyncTask
  13. 二进制,逆向工程,深入理解计算机系统
  14. 计算机中职课程表,计算机专业课程表
  15. java软件开发必读15本书籍
  16. java sqlite sqlite_busy_sqlite3出现SQLITE_BUSY错误码的原因以及解决方法
  17. (附源码)计算机毕业设计SSM原创网络文学管理系统
  18. mutillidae(owasp10)数据库报错
  19. ABP框架Web API跨域问题的解决方案
  20. html如何快速转pDF,如何快速实现pdf转html网页文件 高能方法帮你解决80%职场难题...

热门文章

  1. 流程一改,魔鬼变天使
  2. 莎拉波娃美网新赛服亮相
  3. 问题 L: 求100以内的素数
  4. 初一辍学学php能行吗_那些初中就辍学的小姑娘现在过得如何了?
  5. python的去重函数_python去重函数是什么
  6. np中meshgrid生成二维矩阵matplotlib中imshow生成图形
  7. python中字符串(二)-访问值、更新、转义、运算
  8. LVS负载均衡(LVS简介、三种工作模式、十种调度算法)
  9. Python实现用户登录
  10. canoe变量和信号_CANoe的经验总结及如何进行 CAN Signal layout