这道题要剪枝,不然会超时,还有就是每次参加过的城市下次不能再参观,不然会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. Android-如何开发一个功能强大的图片选择器
  2. Matlab画图,去掉周围白边
  3. 25篇最新CV领域综述性论文速递!涵盖15个方向:目标检测/图像处理/姿态估计/医学影像/人脸识别等方向
  4. 40个很棒的由html5开发的网络游戏案例
  5. concat函数显示小数点包括0
  6. DOS中的 及 用正则表达式中的什么替掉
  7. zset中的score_读懂才会用 : 带你见识 Redis 的 zset
  8. 比特币白皮书 Bitcoin: A Peer-to-Peer Electronic Cash System
  9. bzoj2257瓶子与燃料——最大公约数
  10. Web 端的测试 Selenium 用法必备
  11. 动态心电图信息存储(三)
  12. 华为终端云服务赋能“智能座舱”,打造出行场景的“超级终端”
  13. freeimage.dll
  14. 计算机考试67,注册电气工程师基础考试计算机基础知识试题答案(67)
  15. linux slab 内存 清理,linux系统slab内存占用
  16. c-lodop打印网页内容
  17. HDU - 6287 口算训练 (二分+思维)
  18. rv1108 GMAC 以太网接口的介绍
  19. nginx另类复杂的架构
  20. Fed-SCNN: A Federated Shallow-CNN Recognition Framework for Distracted Driving

热门文章

  1. 在linux中emacs安装package.el
  2. SQL-92标准 中文翻译——定义、记号和约定 (记号)
  3. C++中函数作为参数传递给其他函数
  4. webpack文件夹打包_webpack多入口文件页面打包详解
  5. Python中变量的命名以及输入输出
  6. c语言编写指针函数求和与两数交换值
  7. 儿童电脑学习软件_电脑端英语学习宝藏软件
  8. python界面卡顿_前端页面卡顿、也许是DOM操作惹的祸?
  9. python raise用处_python基础教程python raise的基本使用
  10. SAP License:对煤化工行业的几点思考