http://www.itint5.com/oj/#22

这题一开始直接用暴力的DFS来做,果然到25的规模就挂了.

vector<bool> visited(50, false);
vector<vector<int> > vec_row(50);
vector<vector<int> > vec_col(50); bool findPath(vector<int> &x, vector<int> &y, int idx, int depth, int direction) {
if (depth == x.size()) return true;
visited[idx] = true;
if (direction == 0) {
int row = x[idx];
for (int i = 0; i < vec_row[row].size(); i++) {
if (!visited[vec_row[row][i]]) {
if (findPath(x, y, vec_row[row][i], depth+1, 1))
return true;
}
}
} else {
int col = y[idx];
for (int i = 0; i < vec_col[col].size(); i++) {
if (!visited[vec_col[col][i]]) {
if (findPath(x, y, vec_col[col][i], depth+1, 0))
return true;
}
}
} visited[idx] = false;
return false;
} //如果存在满足条件的遍历,返回true,否则返回false
bool existPath(vector<int> &x, vector<int> &y) {
int k = x.size();
if (k == 0) return true;
for (int i = 0; i < k; i++) {
vec_row[x[i]].push_back(i);
vec_col[y[i]].push_back(i);
}
for (int i = 0; i < k; i++) {
if (findPath(x, y, i, 1, 0) ||
findPath(x, y, i, 1, 1)) {
return true;
}
}
return false;
}

正确的做法是转化成欧拉回路:http://www.itint5.com/discuss/22/%E7%9B%B4%E8%A7%92%E8%B7%AF%E7%BA%BF%E9%81%8D%E5%8E%86%E6%A3%8B%E7%9B%98

这题可以直接转换为欧拉回路(路径)问题,这样,如果有解的时候要输出遍历路径的时候,也比较好办了。
具体的转换方式为:n,m的棋盘,建一个包含n+m个顶点的图G(为了方便说明,类似二分图将其分为两列,左边n个顶点,右边m个顶点,分别代表n行和n列)。对于目标格子(i,j),左边第i个顶点和右边第j个顶点连一条边。最后的问题其实就是问转换之后的图G是否存在欧拉欧拉回路或者欧拉路径。
证明:相邻两步为直角,其实就是从某一行变到某一列。访问图G中的一条边,意味着访问棋盘中的一个目标点。由于图G中的边只连接左边的点(代表某一行)和右边的点(代表某一列),因此访问一条边就意味着从某一行变到了某一列,也就是转直角了。
所以问题变为能否从一点出发访问G中的所有边有且仅有一次。这个就是欧拉回路问题了。

所以欧拉路径是:1.连通;2.奇点为2,为0时是欧拉回路。

这里的连通我用并查集来做。注意写并查集的merge时,要先找到根,再merge。

vector<int> djset;

int find(int i) {
int x = i;
while (djset[x] != x) {
x = djset[x];
}
djset[i] = x;
return x;
} void merge(int i, int j) {
djset[find(i)] = djset[find(j)];
} //如果存在满足条件的遍历,返回true,否则返回false
bool existPath(vector<int> &x, vector<int> &y) {
vector<int> axis(100, 0);
// 计算奇点数目
for (int i = 0; i < x.size(); i++) {
axis[x[i]] = !axis[x[i]]; // 奇偶变换
}
for (int i = 0; i < y.size(); i++) {
axis[y[i]+50] = !axis[y[i]+50];
}
int count = 0;
for (int i = 0; i < axis.size(); i++) {
if (axis[i]) count++;
}
if (count != 0 && count != 2) return false; djset.resize(x.size());
for (int i = 0; i < djset.size(); i++) {
djset[i] = i;
} // 判断连通性
for (int i = 0; i < x.size(); i++) {
for (int j = i+1; j < x.size(); j++) {
if (x[i] == x[j]) {
merge(i, j);
}
}
}
for (int i = 0; i < y.size(); i++) {
for (int j = i+1; j < y.size(); j++) {
if (y[i] == y[j]) {
merge(i, j);
}
}
} for (int i = 0; i < x.size(); i++) {
if (find(i) != find(0)) {
return false;
}
}
return true;
}

  

[itint5]直角路线遍历棋盘的更多相关文章

  1. POJ_2488——骑士遍历棋盘,字典序走法

    Description Background The knight is getting bored of seeing the same black and white squares again ...

  2. day53-马踏棋盘

    马踏棋盘 1.算法优化的意义 算法是程序的灵魂,为什么有些程序可以在海量数据计算时,依旧保持高速计算? 编程中算法很多,比如八大排序算法(冒泡.选择.插入.快排.归并.希尔.基数.堆排序).查找算法. ...

  3. visual_c++外挂教程(详细)

    课程分四个大章节 初级篇,中级篇,进阶篇,高级篇 初级篇内容:编写一个完整的,简单的外挂 C++的数据类型:Byte,Word,DWORD,int,float API函数的调mouse_event,G ...

  4. NOI 题库 8465

    8465  马走日 描述 马在中国象棋以日字形规则移动. 请编写一段程序,给定n*m大小的棋盘,以及马的初始位置(x,y),要求不能重复经过棋盘上的同一个点,计算马可以有多少途径遍历棋盘上的所有点. ...

  5. chineseChess

    最近学习了chineseChess的Qt实现,把一些东西总结一下: 实现功能: 1.人人对战 2.人机对战 3.网络版 一.基础性工作:(人人对战) 1.棋盘和棋子的绘制(QPinter,drawLi ...

  6. noi 8465 马走日

    8465:马走日 查看 提交 统计 提问 总时间限制:  1000ms 内存限制:  1024kB 描述 马在中国象棋以日字形规则移动. 请编写一段程序,给定n*m大小的棋盘,以及马的初始位置(x,y ...

  7. poj 3279 Fliptile

    题意:一个n * m的棋盘,0或1,每次改变一个格子时同时改变上下左右的格子,问用最少次数将棋盘全变成0的策略. 题解:用二进制压缩第一行更改的状态,之后遍历棋盘,如果当前格子为1则改变下方的格子,记 ...

  8. 听说alphago又要挑战sc2了?——我眼中的人工智能

    乱谈: 之前alphago进行的围棋比赛相当火爆. 一时间我的朋友圈都爆了,因为同学以及相关专业的同学都在发这个,毕竟逼格一下就起来了,我也大肆转发.各种角度,不同层次的不同深度的文章也都扫了几眼. ...

  9. web版扫雷小游戏(二)

    接上篇~~第一次写这种技术博客,发现把自己做的东西介绍出来还是一件脑力活,不是那么轻松啊,好吧,想到哪写到哪,流水记录之,待完成之后再根据大家的意见进行修改吧. 游戏实现 根据对扫雷游戏的体验和分析, ...

随机推荐

  1. mysql 导出表结构

    mysql导出数据库各表结构,很简单只要一条命令即可: mysqldump -uxxx -d databasename [,table] > xxx.sql mysqldump中-d参数即为只导 ...

  2. Poj 3030 Nasty Hacks

    1.Link: http://poj.org/problem?id=3030 2.Content: Nasty Hacks Time Limit: 1000MS   Memory Limit: 655 ...

  3. linux 常用软件安装-目录

    nginx apache php mysql oracle tomcat memcached mongodb sqlserver

  4. ES6学习笔记(九)

    1.概述 ES5的对象属性名都是字符串,这容易造成属性名的冲突.比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin模式),新方法的名字就有可能与现有方法产生冲突.如果有一种机制 ...

  5. 淘宝IP地址库采集器c#代码

    这篇文章主要介绍了淘宝IP地址库采集器c#代码,有需要的朋友可以参考一下. 最近做一个项目,功能类似于CNZZ站长统计功能,要求显示Ip所在的省份市区/提供商等信息.网上的Ip纯真数据库,下载下来一看 ...

  6. oracle中的decode的使用

    含义解释:decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值) 该函数的含义如下:IF 条件=值1 THEN RETURN(翻译值1)ELSIF 条件=值2 THEN R ...

  7. Objective-C中class、Category、Block的介绍

    @class 当定义一个类,必须为编译器提供两组消息,第一组(接口部分.h):构建类的实例的一个基本蓝图.必须指定类名,类的超类,类的实例变量和类型的列表,最后是类的方法的声明.第二组(实现部分.m) ...

  8. Linux进程间通信IPC学习笔记之同步二(Posix 信号量)

    Linux进程间通信IPC学习笔记之同步二(Posix 信号量)

  9. 1010. Radix (25)

    Given a pair of positive integers, for example, 6 and 110, can this equation 6 = 110 be true? The an ...

  10. Eclipse--Team--SVN--URL修改

    1.团队开发服务器,有的时候会更换地址 解决: eclipse--菜单Windows-Show View-others-svn--svn资源库 打开资源库面板 右击http://localhost:9 ...