我被小学生难住了(各位大哥试试)

glunoy 2007-06-08 07:31:11
一天,表妹问我:
00000
00000
00000
0000
00000
怎样用一条线连起来?不能斜画 就是说比如: 左上0.0 不能连到1.1 另外0.0 不能直接连到 2.0 就是说只有上下左右能连 而且每个0只能连一次。
我想了想 咱好歹是个学计算机的。这类类似穷举的问题就交给计算机来做。没想到真正实现的时候却不知从何下手!
汗颜啊。如果采用深度搜索,怎样才能给走过的路径置一个位 以免死循环呢?另外要采用什么数据结构才好?堆栈貌似不太合适 队列也不成。咋办?
...全文
616 22 打赏 收藏 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
glunoy 2007-06-20
  • 打赏
  • 举报
回复
高手!偶啥也看不懂了
iceheart 2007-06-18
  • 打赏
  • 举报
回复
只需证明一个具有奇数行奇数列的矩阵上的所有点是无法用一条闭合的折线连接起来
milksea 2007-06-17
  • 打赏
  • 举报
回复
我是在去掉一个角的情况下统计的,另外起点和终点是等价的(倘不以左上角为起/终点,可立即推出矛盾),所以倒是没什么错。当然,laizhenyuan的方法更简洁,我之前确实证复杂了。
laizhenyuan 2007-06-17
  • 打赏
  • 举报
回复
milksea(航航 | 啥都不会咋办)的思路是对的,不过证明过程有误,不一定是要黑的作为起点,统计黑白位置的数量也有误。
由图可以看出不论怎么走,根据黑白相间的路线统计出都应该是黑的位置相等或相差一个,而这个图白的位置多出两个,明显是不可能形成黑白相间的路线的,因此无解。
Vitin 2007-06-16
  • 打赏
  • 举报
回复
如果注释掉以下两行(即去掉 3,0 这个不可通过点)
zero_graph[3][0] = row * GRAPH_SIZE + col + POSITIVE_OFFSET;
step_num--;

则可以立即得到一个解(根据StepZeroGraph实现,为按列遍历),递归25次。
Vitin 2007-06-16
  • 打赏
  • 举报
回复
编了个程序,结果证明是无解的。

#include <iostream>
using std::cout;
using std::endl;

const size_t GRAPH_SIZE = 5;
const size_t POSITIVE_OFFSET = 1;

bool StepZeroGraph(size_t zero_graph[][GRAPH_SIZE], size_t row, size_t col,
size_t& step_num)
{

if ( --step_num == 0)
{
return true;
}

static size_t try_step[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };

for (size_t i = 0; i < sizeof(try_step) / sizeof(try_step[0]); i++)
{
size_t next_row = row + try_step[i][0];
size_t next_col = col + try_step[i][1];
if ( next_row >= 0
&& next_row < GRAPH_SIZE
&& next_col >= 0
&& next_col < GRAPH_SIZE)
{
if (zero_graph[next_row][next_col] != 0)
continue;

zero_graph[row][col] = next_row*GRAPH_SIZE + next_col + POSITIVE_OFFSET;
if (StepZeroGraph(zero_graph, next_row, next_col, step_num))
return true;
}
}

zero_graph[row][col] = 0;
step_num++;
return false;
}

inline void PrintResult(size_t row, size_t col, size_t& step_num)
{
cout << step_num++ << ":\t"
<< "row = " << row << "\t"
<< "col = " << col << endl;
}

int main()
{
size_t zero_graph[GRAPH_SIZE][GRAPH_SIZE] = {0};
size_t step_num = GRAPH_SIZE*GRAPH_SIZE;

size_t row = 4;
size_t col = 0;
zero_graph[3][0] = row * GRAPH_SIZE + col + POSITIVE_OFFSET;
// zero_map[3][0]这里不能通过,所以设一个非0值
// 从题义知,zero_map[4][0]必然是开始或结束点
// 不失一般性,将zero_map[4][0]设为开始点
step_num--;


if (StepZeroGraph(zero_graph, row, col, step_num))
{
while (zero_graph[row][col] != 0)
{
PrintResult(row, col, step_num);
size_t next = zero_graph[row][col] - POSITIVE_OFFSET;
row = next / GRAPH_SIZE;
col = next - row * GRAPH_SIZE;
}
PrintResult(row, col, step_num);
}
else
{
cout << "Solution NOT FOUND !!" << endl;
}

system("pause");
}

输出是 Solution NOT FOUND !!
在调试时插入计数器发现,一共递归了43207次。

看了一下LS的证明,我觉得完全正确。

milksea 2007-06-16
  • 打赏
  • 举报
回复
缺角的×位置不大对,大家旋转一下看哈……
milksea 2007-06-16
  • 打赏
  • 举报
回复
给个无解的证明吧,结帖吧。

对此题,可以这样看。
容易看出,如果有解,左上角的圈肯定是起点或终点。我们去掉这个位置,无妨设它下面的位置是起点。
现在把所有的位置交替涂色:
○×○●○
●○●○●
○●○●○
●○●○●
○●○●○
可以看出,除去左上角后,黑的位置比白的位置少一个。但现在是从黑位置开始走,连成的线肯定是“黑白黑白……黑”或“黑白黑白……白”,要么黑白一样多,要么黑的比白的多一个,导致矛盾。所以无解。
JoyerHuang_悦 2007-06-14
  • 打赏
  • 举报
回复
大伙儿都被自己的计算机思维给害了。。
这道题又没有让给出全解,一个解就可以了。。。

就走一条蛇行线好了。。

-----
----|
|--||
||-||
|---|
From_China 2007-06-14
  • 打赏
  • 举报
回复
菜鸟今天报道!开始闯荡江湖!
marrco2005 2007-06-14
  • 打赏
  • 举报
回复
mark
free1879 2007-06-13
  • 打赏
  • 举报
回复
NP
hamlet0168 2007-06-13
  • 打赏
  • 举报
回复
此题无解
laohuang008 2007-06-13
  • 打赏
  • 举报
回复
1。用矩阵表示这张图
2。用1、2、4、8分别代表上下左右,比如说已经尝试过了上和下,就存3
3。用stack存路径
我想,差不多了吧。
(不过,这个问题好像真的没解)
gdckwxiao_swjtu 2007-06-10
  • 打赏
  • 举报
回复
做了半天,没做出来,现在的小学出的题真是让人难以理解啊!
感觉总是最后一条线连不好。
glunoy 2007-06-10
  • 打赏
  • 举报
回复
不能跨行 只能相邻的行
milksea 2007-06-09
  • 打赏
  • 举报
回复
深度优先搜索的话,和走地图是一回事,有一个标记矩阵就够了,不难。
milksea 2007-06-09
  • 打赏
  • 举报
回复
不是欧拉图,是哈密尔顿(Hamilton)图。
这个问题目前没有好的算法,只有指数级别的穷举。
何哀何欢 2007-06-09
  • 打赏
  • 举报
回复
0-0-0-0-0
........|
0-0-0-0-0
|
0-0-0-0-0
........|
0-0-0-0 |
|.......|
0-0-0-0-0
何哀何欢 2007-06-09
  • 打赏
  • 举报
回复
没看懂,这样算吗?

0-0-0-0-0
|
0-0-0-0-0
|
0-0-0-0-0
|
0-0-0-0 |
| |
0-0-0-0-0
加载更多回复(2)

3,881

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧