题意:平面有k个障碍点。从(0,0)出发,第一次走1个单位,……,第n次走n个单位,恰好回到(0,0),每次必须转弯90°,图形可以自交,但不能经过障碍点。按字典序输出所有移动序列,并输出序列总数。

分析:

1、障碍点可能在出发点。

2、注意拐点不能重复!!!

3、按字典序输出。

#pragma comment(linker, "/STACK:102400000, 102400000")
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<iostream>
#include<sstream>
#include<iterator>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#define Min(a, b) ((a < b) ? a : b)
#define Max(a, b) ((a < b) ? b : a)
typedef long long ll;
typedef unsigned long long llu;
const int INT_INF = 0x3f3f3f3f;
const int INT_M_INF = 0x7f7f7f7f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const ll LL_M_INF = 0x7f7f7f7f7f7f7f7f;
const int dr[] = {, , , -};
const int dc[] = {, , -, };
const int MOD = 1e9 + ;
const double pi = acos(-1.0);
const double eps = 1e-;
const int MAXN = + ;
const int MAXT = + ;
using namespace std;
int vis[MAXN][MAXN];
int mark[MAXN][MAXN];
int ans[];
int n;
int cnt;
map<int, char> mp;
void init(){
string s = "ensw";
for(int i = ; i < ; ++i){
mp[i] = s[i];
}
}
bool judge(int x, int y, int tx, int ty, int length){
if((vis[tx][ty] || mark[tx][ty]) && !(tx == && ty == && length == n)) return false;//重复经过某个拐点,但此点不是走了n步后到达的原点
if(x != tx){
if(x > tx) swap(x, tx);
for(int i = x + ; i < tx; ++i){
if(vis[i][y]){
return false;
}
}
return true;
}
if(y != ty){
if(y > ty) swap(y, ty);
for(int i = y + ; i < ty; ++i){
if(vis[x][i]){
return false;
}
}
return true;
}
}
void dfs(int x, int y, int length){
if(length == n + ){
if(x == && y == ){
++cnt;
for(int i = ; i <= n; ++i){
printf("%c", mp[ans[i]]);
}
printf("\n");
}
}
else{
//必须90°转弯,所以只能向两个方向走
int dir[];
if(ans[length - ] == ){//东
dir[] = ;//北
dir[] = ;//南
}
else if(ans[length - ] == ){//北
dir[] = ;
dir[] = ;
}
else if(ans[length - ] == ){//南
dir[] = ;
dir[] = ;
}
else if(ans[length - ] == ){//西
dir[] = ;
dir[] = ;
}
for(int i = ; i < ; ++i){
int tx = x + dr[dir[i]] * length;
int ty = y + dc[dir[i]] * length;
if(judge(x, y, tx, ty, length)){
ans[length] = dir[i];
++mark[tx][ty];
dfs(tx, ty, length + );
--mark[tx][ty];
}
}
}
}
int main(){
init();
int T;
scanf("%d", &T);
while(T--){
memset(vis, , sizeof vis);
memset(ans, , sizeof ans);
memset(mark, , sizeof mark);
cnt = ;
int k;
scanf("%d%d", &n, &k);
while(k--){
int x, y;
scanf("%d%d", &x, &y);
vis[x + ][y + ] = ;
}
if(vis[][]){
printf("Found 0 golygon(s).\n\n");
continue;
}
int x = ;//下标不能为负,所以所有坐标加255,原点在(255,255)。
int y = ;
int length = ;
mark[x][y] = ;
for(int i = ; i < ; ++i){//东,北,南,西
int tx = x + dr[i] * length;
int ty = y + dc[i] * length;
if(judge(x, y, tx, ty, length)){//向此方向走length步无障碍物
ans[length] = i;
++mark[tx][ty];
dfs(tx, ty, length + );
--mark[tx][ty];
}
}
printf("Found %d golygon(s).\n\n", cnt);
}
return ;
}

UVA - 225 Golygons (黄金图形)(回溯)的更多相关文章

  1. UVA225 Golygons 黄金图形(dfs+回溯)

    剪枝1:在同一个维度上的点具有相同的奇偶性,如果奇数数量只有奇数个那么一定不能返回原点. 剪枝2:当前位置怎么也走不回去. 3:沿途判断障碍即可. 在oj上提交0.347s,最快的0.012s,应该有 ...

  2. Uva 225 Golygons

    这道题如果直接用Dfs,运气好的话是可以直接过的. 但如果要在Dfs的基础上加快速度,剪枝是必不可少的. 我的剪枝策略: 1.当前点(x,y)回到出发点至少需要 |x| +| y| 步,如果剩余的步数 ...

  3. UVa 225 黄金图形(回溯+剪枝)

    https://vjudge.net/problem/UVA-225 题意:平面上有k个障碍点,从(0,0)出发,第一次走1个单位,第二次走2个单位,...第n次走n个单位,最后恰好回到(n,n).每 ...

  4. UVa 129 Krypton Factor【回溯】

    学习的紫书的回溯,理解起来还是好困难的说啊= = #include<iostream> #include<cstdio> #include<cstring> #in ...

  5. UVa 1602 网格动物(回溯)

    https://vjudge.net/problem/UVA-1602 题意:计算n连通块不同形态的个数. 思路: 实在是不知道该怎么做好,感觉判重实在是太麻烦了. 判重就是判断所有格子位置是否都相同 ...

  6. UVa 129 Krypton Factor (DFS && 回溯)

    题意 : 如果一个字符串包含两个相邻的重复子串,则称它是“容易的串”,其他串称为“困难的 串”.例如,BB.ABCDACABCAB.ABCDABCD都是容易的串,而D.DC.ABDAB. CBABCB ...

  7. uva 387 A Puzzling Problem (回溯)

     A Puzzling Problem  The goal of this problem is to write a program which will take from 1 to 5 puzz ...

  8. UVA - 524 Prime Ring Problem(dfs回溯法)

    UVA - 524 Prime Ring Problem Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & % ...

  9. UVa 167(八皇后)、POJ2258 The Settlers of Catan——记两个简单回溯搜索

    UVa 167 题意:八行八列的棋盘每行每列都要有一个皇后,每个对角线上最多放一个皇后,让你放八个,使摆放位置上的数字加起来最大. 参考:https://blog.csdn.net/xiaoxiede ...

随机推荐

  1. spring SpEL--转

    原文:http://www.tuicool.com/articles/Jbq2QnM 概要: Spring表达式语言:SpEL Spring表达式语言 (简称 SpEL ):是一个 支持运行时查询和操 ...

  2. 树 插件 ztree 的基本用法

    因业务需要 用到 ztree 插件 第一次用tree插件上手有点难度 官网 http://www.treejs.cn/v3/main.php#_zTreeInfo 第一步:初始化树,树的所有数据从后台 ...

  3. YUV 和 YCbCr 辨析

    YCbCr或Y'CbCr 是在世界数字组织视频标准研制过程中作为ITU-R BT1601 建议的一部分, 其实是YUV经过缩放和偏移的翻版. 通常会用于影片中的影像连续处理,或是数字摄影系统中. 其中 ...

  4. Django 学习组件分页器与自定制分页器

    一.Django 分页器 1.django的分页器基础版 (1)首先是基础数据分别为 from django.db import models # Create your models here. c ...

  5. Scrapy 框架结构及工作原理

    1.下图为 Scrapy 框架的组成结构,并从数据流的角度揭示 Scrapy 的工作原理 2.首先.简单了解一下 Scrapy 框架中的各个组件 组       件 描      述 类   型 EN ...

  6. change事件和input事件的区别

    input事件: input事件在输入框输入的时候回实时响应并触发 change事件: change事件在input失去焦点才会考虑触发,它的缺点是无法实时响应.与blur事件有着相似的功能,但与bl ...

  7. Linux centosVMware df命令、du命令、磁盘分区

    一.df命令 df(disk filesystem的简写)用于查看自己挂载磁盘的总容量.使用容量.剩余容量,可以不加任何参数,默认以KB为单位. [root@davery ~]# df文件系统 1K- ...

  8. JDBC--处理事务

    1.事务是指一组逻辑操作单元,使数据从一种状态转换到另一种状态. 2.事务的四个属性: --1)原子性:事务是一个不可分割的工作单位,事务中的操作要么都发生要么都不发生: --2)一致性:事务必须是数 ...

  9. Day3-D-Protecting the Flowers POJ3262

    Farmer John went to cut some wood and left N (2 ≤ N ≤ 100,000) cows eating the grass, as usual. When ...

  10. @vue-cli的安装及vue项目创建

    1.安装 Node.js & Vue CLI @vue/cli3,是vue-进行搭建的脚手架项目,它本质上是一个全局安装的 npm 包,通过安装它,可以为终端提供 vue 命令,进行vue项目 ...