这道题如果直接用Dfs,运气好的话是可以直接过的。

  但如果要在Dfs的基础上加快速度,剪枝是必不可少的。

  我的剪枝策略:

    1.当前点(x,y)回到出发点至少需要 |x| +| y| 步,如果剩余的步数不足以达到当前所需的最小步数,则剪枝。比如在没有障碍的情况下,要求在4次行走时完成回路,如果第三次走到(2,4),那么计算得要回到出发点最少需要5步,但此时剩余4步,不可能走回出发点,因此可以剪枝。

    2.如果当前 x 或 y 的值,超过了所能走的步数的一半,则剪枝

    3.如果没有在最后一步就走到出发点,就剪枝。比如在没有障碍的情况下,要求在20次行走时完成回路,那么就很容易在第8次的时候就走回出发点(题目中的例子就是8次回到出发点),此时已经没有继续走第9次,因此可以剪枝。

  需要额外注意的一点是,此题中的x,y坐标是直角坐标系的坐标,而不是矩阵的坐标。

  

// #include <iostream>
// #include <cstring>
// #include <cstdio>
// #include <algorithm>
// #include <vector>
#include <bits/stdc++.h> using namespace std; struct Point{
int x, y;
Point(){}
Point(int a, int b){
x = a; y = b;
}
};
vector<Point> point;
int dirPath[30];
int dir[4][2] = {1, 0, 0, 1, 0, -1, -1, 0};
int revDir[4] = {3, 2, 1, 0};
char dirChar[10] = "ensw";
int N, K, C; void Read() {
scanf("%d%d", &N, &K);
point.clear();
int x, y;
for(int i=0; i<K; ++ i) {
scanf("%d%d", &x, &y);
point.push_back(Point(x, y));
}
} const int MAXN = 600;
const int OFFSET = 256;
bool vis[MAXN][MAXN];
bool IsVis(const Point &p) {
return vis[p.x+OFFSET][p.y+OFFSET];
} void SetVis(const Point &p, bool flag) {
vis[p.x+OFFSET][p.y+OFFSET] = flag;
} bool CanPut(const Point& p1, const Point& p2) {
if(p1.x == p2.x) {
for(size_t i = 0; i < point.size(); ++ i) {
if(point[i].x == p1.x && point[i].y >= p1.y && point[i].y <= p2.y) {
return false;
}else if(point[i].x == p1.x && point[i].y >= p2.y && point[i].y <= p1.y) {
return false;
}
}
} else if(p1.y == p2.y) {
for(size_t i = 0; i < point.size(); ++ i) {
if(point[i].y == p1.y && point[i].x >= p1.x && point[i].x <= p2.x) {
return false;
}else if(point[i].y == p1.y && point[i].x >= p2.x && point[i].x <= p1.x) {
return false;
}
}
}
return true;
} void Print() {
for(int i=1; i<N+1; i++) {
printf("%c", dirChar[dirPath[i]]);
}
printf("\n");
} void Dfs(Point p, int key) {
if(abs(p.x) + abs(p.y) > (key+N) * (N-key+1) >> 1) {
return ;
}
if(abs(p.x) > (1+N) * N >> 1 || abs(p.y) > (1+N) * N >> 1) {
return ;
}
if(key == N + 1) {
if(p.x == 0 && p.y == 0) {
++ C;
Print();
}
return ;
} else if(p.x == 0 && p.y == 0) {
return ;
}
for(int i=0; i<4; i++) {
if(dirPath[key - 1] != i && i != revDir[dirPath[key - 1]]) {
Point next( p.x + key * dir[i][0], p.y + key * dir[i][1] );
if(!IsVis(next) && CanPut(p, next)) {
dirPath[key] = i;
SetVis(next, true);
Dfs(next, key+1);
SetVis(next, false);
}
}
}
} int main() {
int T;
cin >> T;
while(T --) {
Read();
memset(vis, false, sizeof(vis));
Point start(0, 0);
C = 0;
for(int i=0; i<4; i++) {
Point next( start.x+dir[i][0], start.y+dir[i][1] );
if(CanPut(start, next)) {
dirPath[1] = i;
SetVis(next, true);
Dfs(next, 2);
SetVis(next, false);
}
}
printf("Found %d golygon(s).\n", C);
printf("\n");
}
return 0;
}

Uva 225 Golygons的更多相关文章

  1. UVA - 225 Golygons (黄金图形)(回溯)

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

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

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

  3. UVa 10012 - How Big Is It? 堆球问题 全排列+坐标模拟 数据

    题意:给出几个圆的半径,贴着底下排放在一个长方形里面,求出如何摆放能使长方形底下长度最短. 由于球的个数不会超过8, 所以用全排列一个一个计算底下的长度,然后记录最短就行了. 全排列用next_per ...

  4. Fast Matrix Operations(UVA)11992

    UVA 11992 - Fast Matrix Operations 给定一个r*c(r<=20,r*c<=1e6)的矩阵,其元素都是0,现在对其子矩阵进行操作. 1 x1 y1 x2 y ...

  5. Android Weekly Notes Issue #225

    Android Weekly Issue #225 October 2nd, 2016 Android Weekly Issue #225 本期内容包括: Android 7.0的Quick Sett ...

  6. uva 1354 Mobile Computing ——yhx

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABGcAAANuCAYAAAC7f2QuAAAgAElEQVR4nOy9XUhjWbo3vu72RRgkF5

  7. UVA 10564 Paths through the Hourglass[DP 打印]

    UVA - 10564 Paths through the Hourglass 题意: 要求从第一层走到最下面一层,只能往左下或右下走 问有多少条路径之和刚好等于S? 如果有的话,输出字典序最小的路径 ...

  8. UVA 11404 Palindromic Subsequence[DP LCS 打印]

    UVA - 11404 Palindromic Subsequence 题意:一个字符串,删去0个或多个字符,输出字典序最小且最长的回文字符串 不要求路径区间DP都可以做 然而要字典序最小 倒过来求L ...

  9. UVA&&POJ离散概率与数学期望入门练习[4]

    POJ3869 Headshot 题意:给出左轮手枪的子弹序列,打了一枪没子弹,要使下一枪也没子弹概率最大应该rotate还是shoot 条件概率,|00|/(|00|+|01|)和|0|/n谁大的问 ...

随机推荐

  1. 删除Lb重复的数,用La输出(顺序表)

    #include<stdio.h> typedef int A; const int LIST_INIT_SIZE=100; const int LISTINCRMENT=10; type ...

  2. activemq demo指南

    queue与topic的技术特点对比   topic queue 概要 Publish Subscribe messaging 发布订阅消息 Point-to-Point 点对点 有无状态 topic ...

  3. linux用户管理最常用的三个文件说明(不完整版)

    涉及到三个文本文件:/etc/passwd /etc/shadow /etc/group 文件相关: /etc/passwd和用户名相关 /etc/shadow和密码相关 /etc/group和用户所 ...

  4. feof()和EOF的用法(转载)

    查看 stdio.h 可以看到如下定义: #define  EOF  (-1) #define  _IOEOF  0x0010 #define  feof(_stream)  ((_stream)-& ...

  5. IOS 学习笔记(1) 视图UIViewController

    1.UIViewController *newController=[[UIViewController alloc] initWithNibName:@"XXX" bundle: ...

  6. web api 开发之 filter

     1.使用filter之前应该知道的(不知道也无所谓,哈哈!) 谈到filter 不得不先了解下aop(Aspect Oriented Programming)面向切面的编程.(度娘上关于aop一大堆 ...

  7. ASP.NET jQuery 随笔 使用jQuery UI的Autocomplete方法实现文本框的自动搜索填充功能

    首先当然是去下载JQuery UI ,这里这里是下载地址http://jqueryui.com/ 第一步是点击这里 第二步选择你想要下载的主题进行下载 我这里是选择的cupertino主题包 点击圆圈 ...

  8. 操作 IoT 设备内嵌 SQLite

    Win10 IoT C#开发 5 - 操作 IoT 设备内嵌 SQLite 数据库 CURD   Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,与以往的Windows版本 ...

  9. Protel99se轻松入门:特殊技巧和高级设置(一)

    这里简单介绍一下自动布线和手动布线方面的设置问题 1.如何进入PCB的这个布线规则选项: 2.电气安全距离的设置 3.导线宽度的设置 4.学会了设置图层就可以做单面板以及多层板,而不只是双面板 5.布 ...

  10. Oracle 快照及 dblink使用 (两台服务器数据同步)

    /*一.创建dblink:*/ --1.在目的数据库上,创建dblin drop database link dblink_anson; Create public database link dbl ...