Uva 225 Golygons
这道题如果直接用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的更多相关文章
- UVA - 225 Golygons (黄金图形)(回溯)
题意:平面有k个障碍点.从(0,0)出发,第一次走1个单位,……,第n次走n个单位,恰好回到(0,0),每次必须转弯90°,图形可以自交,但不能经过障碍点.按字典序输出所有移动序列,并输出序列总数. ...
- UVa 225 黄金图形(回溯+剪枝)
https://vjudge.net/problem/UVA-225 题意:平面上有k个障碍点,从(0,0)出发,第一次走1个单位,第二次走2个单位,...第n次走n个单位,最后恰好回到(n,n).每 ...
- UVa 10012 - How Big Is It? 堆球问题 全排列+坐标模拟 数据
题意:给出几个圆的半径,贴着底下排放在一个长方形里面,求出如何摆放能使长方形底下长度最短. 由于球的个数不会超过8, 所以用全排列一个一个计算底下的长度,然后记录最短就行了. 全排列用next_per ...
- Fast Matrix Operations(UVA)11992
UVA 11992 - Fast Matrix Operations 给定一个r*c(r<=20,r*c<=1e6)的矩阵,其元素都是0,现在对其子矩阵进行操作. 1 x1 y1 x2 y ...
- Android Weekly Notes Issue #225
Android Weekly Issue #225 October 2nd, 2016 Android Weekly Issue #225 本期内容包括: Android 7.0的Quick Sett ...
- uva 1354 Mobile Computing ——yhx
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABGcAAANuCAYAAAC7f2QuAAAgAElEQVR4nOy9XUhjWbo3vu72RRgkF5
- UVA 10564 Paths through the Hourglass[DP 打印]
UVA - 10564 Paths through the Hourglass 题意: 要求从第一层走到最下面一层,只能往左下或右下走 问有多少条路径之和刚好等于S? 如果有的话,输出字典序最小的路径 ...
- UVA 11404 Palindromic Subsequence[DP LCS 打印]
UVA - 11404 Palindromic Subsequence 题意:一个字符串,删去0个或多个字符,输出字典序最小且最长的回文字符串 不要求路径区间DP都可以做 然而要字典序最小 倒过来求L ...
- UVA&&POJ离散概率与数学期望入门练习[4]
POJ3869 Headshot 题意:给出左轮手枪的子弹序列,打了一枪没子弹,要使下一枪也没子弹概率最大应该rotate还是shoot 条件概率,|00|/(|00|+|01|)和|0|/n谁大的问 ...
随机推荐
- U3d 手游优化概述
移动平台瓶颈 体积小 芯片要求改 功耗小 影响计算系能 带宽小 传输方面受限 性能优化 资源方面 美术方面 自带地形(地形是非常占用资源的) a.控制地形的分辨率 b.地形高度图尺寸小于257 c.地 ...
- handlebar.js使用
官方网站:http://handlebarsjs.com/ 下载及查看使用帮助,或者用百度cdn引用 一.定义模板 <script id="entry-template" t ...
- c#计算文件的MD5值
代码: /// <summary> /// 计算文件的 MD5 值 /// </summary> /// <param name="fileName" ...
- ubuntu下使用codeblocks
集成开发环境搭建 1. 安装build-essential 方法: sudo apt-get install build-essential 作用:提供编译程序必须软件包的列表信息,编译程序有了这个软 ...
- Android开发中出现cannot be resolved to a variable错误,也就是R文件不能生成。
最近开始学过习Android开发,配置完成开发环境后,在创建第一个Android项目就出现了cannot be resolved to a variable错误,也就是R文件不能生成的问题. 以下是从 ...
- Mac 让 iTerm2 记住用户名密码 expect 脚本
刚刚用iTerm2的时候,总是要一遍遍的敲用户名.密码. 我在想, 能不能像Windows的软件一样,可以直接让软件记住.然后只要点击一下,就直接ssh到远程服务器上面去了. 之后经过搜索,可以用ex ...
- HDU 2227 Find the nondecreasing subsequences
题目大意:给定一个序列,求出其所有的上升子序列. 题解:一开始我以为是动态规划,后来发现离散后树状数组很好做,首先,c保存的是第i位上升子系列有几个,那么树状数组的sum就直接是现在的答案了,不过更新 ...
- Mysql5.6.24 zip解压缩版配置及修改默认编码方法
win64位下载地址: http://dev.mysql.com/downloads/file.php?id=456319 下载完毕后解压 配置环境变量 在Path后加上mysql解压后bin文件夹所 ...
- hdoj 3555 Bomb(DFA+dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3555 思路分析:该问题要求求解1—N中的数中含有49的数的个数,可以使用DFA来递推dp公式:详细解释 ...
- Ants(思维)
Ants Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 12893 Accepted: 5637 Description ...