题意:平面有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. bat批处理下如何像shell一样将命令执行的效果赋值给变量

    在bat下如何实现像shell一样,把执行命令行后的结果赋值给变量呐? 刚开始,可真难为到我了.随着对bat批处理知识熟悉的加深. 学习到了!!! 举个 栗子: svnlook  uuid  C:\R ...

  2. 更新Android Studio,提示后直接点更新即可。gradle 两种更新方法,我用的第二种:手动添加gradle

    直接更新即可. 更新完毕后,随即会让你更新gradle,但是会一直更新一直更新...... 解决方法: 第一种方法: 手动下载Android Studio 对应的 gradle版本,然后设置一下即可. ...

  3. 郁闷的 IE6/7/8 所遇兼容问题

    IE6,7只支持inline元素设置为inline-block,但不支持block元素转换成inline-block,所以非inline元素在IE6,7下要转换成inline-block,需先转换成i ...

  4. delphi中的pansichar和pchar等类型的区别

    varc: Char; {Char 类型的取值范围是: #0..#255, 用十六进制表示是: #$0..#$FF}begin{用十进制方式赋值:}c := #65;ShowMessage(c); { ...

  5. Sqlserver2012 使用sql语句增加(或删除)表一个字段

    前言 Mark在SqlServer 2012 的数据库使用sql语句增加(或删除)一张表的一个字段. 使用Sql语句增加表的一个字段 [1]语法: alter table table_name add ...

  6. SessionAttributes注解

    SessionAttributes注解: a.该注解只能应用在类上: b.该注解用于将Map.ModelMap.Model或ModelAndView中的数据暂存到HttpSession中以使其可以在多 ...

  7. Liunx 如何查看80端口被哪个程序所占用

    场景:启服务时一直报80端口被占用 解决方: 1.首先查看下 80 端口的使用情况 netstat -anp|grep 80 查看80端口被被占用的PID 2.根据这个PID 来查看被哪个程序在使用 ...

  8. react基础总结

    React的特点: 1.声明式: 可以声明式的在js中写html结构: 注意: react是用很像 js 的语言写标签; const jsx = <div className="app ...

  9. BEC合约整数溢出漏洞还原与分析

    一.币圈一秒,人间一年 有道是币圈一日,人间一年.这个说法又得升级了,叫币圈一秒,人间一年. 前不久,币圈又出大事啦.BEC智能合约被爆出整数溢出漏洞,导致黑客能无限印币,在一次交易中,也就那么几秒钟 ...

  10. SSH框架结构分析

    分类: 工作问题2012-03-29 18:10 1511人阅读 评论(0) 收藏 举报 框架sshhibernatespringstrutsdao 最近在弄j2ee,发现还是学到了很多东西,心情ha ...