题意:平面有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. 第2节 Scala中面向对象编程:1、类的定义;2、类的构造器;3、object和伴生对象;4、apply和main方法

    6.    类.对象.继承.特质 Scala的类与Java.C++的类比起来更简洁,学完之后你会更爱Scala!!! 6.1.   类 6.1.1.    类的定义 package cn.itcast ...

  2. matlab学习 — 实现简单的爬虫

    这里复杂的情况暂时不考虑..测试网址为pixiv的每日排行榜 = = url = 'https://www.pixiv.net/ranking.php?mode=daily' text = webre ...

  3. Flask - 闪现flash

    1. 像snap一样阅后即焚,在服务器端临时存储数据的地方,如显示错误信息.(也可以用session实现) 2. Flash的底层是session做的,所以要secret_key.可以看源码 3. f ...

  4. java程序员,英语那点事

    本文选自<Java程序员,上班那点事儿>有时候如果应聘到了一个有外资背景的公司或者这个公司的很多人都有海外或外资工作背景时,你 也许还会用到一些日常工作交流时候的词汇.        比如 ...

  5. Java程序与其它进程的数据通信

    Java程序中可以启动其他的应用程序,这种在Java中启动的进程称为子进程,启动子进程的Java程序称为父进程,其实这个父进程就是一个Java虚拟机1.在Java程序中可以用Process类的实例对象 ...

  6. 自定义组装json对象

    组装json对象 public string strTree(DataTable dt, string type, string state) { string strjosn = "&qu ...

  7. sklearn中调用集成学习算法

    1.集成学习是指对于同一个基础数据集使用不同的机器学习算法进行训练,最后结合不同的算法给出的意见进行决策,这个方法兼顾了许多算法的"意见",比较全面,因此在机器学习领域也使用地非常 ...

  8. 吴裕雄--天生自然HADOOP操作实验学习笔记:pvuv统计案例理论

    实验目的 复习pv.uv的概念和原理 了解pv.uv的实际意义和获取方法 实验原理 前面我们已经基于mapreduce进行数据的etl处理,实验有很多不足之处,这次实验我们是基于url数据进行pv和u ...

  9. myeclipse汉化

    MyEclipse默认安装在计算机用户目录下面,安装完成后对MyEclipse快捷方式使用鼠标右键属性---打开文件位置--进入安装的目录下面即可看到 zh_CN.7z解压缩将zh_CN目录文件放到 ...

  10. Python 网络编程之网络协议(未完待续)

    一:网络编程从两大架构开始 1.网络开发的两大架构 c/s 架构 : client  server B/S 架构 : Brower  server (1)bs 和 cs 架构之间的关系? (2)哪一种 ...