题意:平面有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. 第1节 Scala基础语法:scala中的方法源码分析

    val list=List(1,2,3,4) list.reduce((x:Int,y:Int)=>x+y)--->list.reduceLeft((x:Int,y:Int)=>x+ ...

  2. Java中正确使用hashCode和equals方法

    在这篇文章中,我将告诉大家我对hashCode和equals方法的理解.我将讨论他们的默认实现,以及如何正确的重写他们.我也将使用Apache Commons提供的工具包做一个实现. 目录: hash ...

  3. Linux centosVMware Linux监控平台介绍、zabbix监控介绍、安装zabbix、忘记Admin密码如何做

    一.Linux监控平台介绍 cacti.nagios.zabbix.smokeping.open-falcon等等 cacti.smokeping偏向于基础监控,成图非常漂亮 cacti.nagios ...

  4. Oracle如何修改密码?如何解锁scott用户?

    修改密码: scott用户的密码不对,进入管理员用户,修改scott用户密码即可 或者这样修改密码:在运行栏里面敲:sqlplus(空格)/nolog 回车接着在弹出框里面敲:conn sys/pas ...

  5. postgresql shell脚本传递参数并执行sql脚本并

    参考: https://stackoverflow.com/questions/7389416/postgresql-how-to-pass-parameters-from-command-line ...

  6. AndroidQ强势来袭,国产自研系统还有未来吗?

    我的小米8在重启时,屏幕上总会出现那句让人印象深刻的话--"Powered by android".事实上,几乎所有Android手机都会出现这几个单词--国产智能手机也不例外.这 ...

  7. threading 多线程

    # coding:utf- import time from threading import Thread def foo(x):#这里可以带参数def foo(x) print "foo ...

  8. Flask与Django哪个更好更实用呢?砖家是这么认为的

        这一周我打算做一个 Flask 教程.本文先把 Flask 和 Django 做一个比对,因为我对这两个 Python Web 框架都有实际的开发经验.希望我可以帮助您选择学习哪个框架,因为学 ...

  9. android 根据res文件夹下(如res/raw)文件名获取其id

    android 根据res文件夹下(如res/raw)文件名获取其id //测试是否能够获取其资源ID int treeId = mv.getResources().getIdentifier(fil ...

  10. php 增删改查范例(1)

    主页index.php(含多条件查询): <?php$db = new Mysqli("localhost","root","root" ...