一道面试题 牛人来搞下

lxh8810 2009-05-12 10:46:25
面试挂了
求救:
一个7X7二维数组如下:
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 1
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
请你用一条线将所有的0连起来。
该线不能通过1,也不能有重复。
...全文
300 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
diablox0147 2009-05-14
  • 打赏
  • 举报
回复
好像是因为如果穿的话一定会经过与前面那个本身颜色不同的子,如果多2个一样颜色的话必定有其中一个多出来无法穿起来。。。最终点只能是死胡同,因为剩下的那个绝对不在这个最后这个子的旁边...
不知道有没有说明白
hityct1 2009-05-14
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 hityct1 的回复:]
引用 17 楼 zhangyan_wt 的回复:
无解。

将棋盘黑白相间染色,保证黑子上下左右都是白子,白子上下左右都是黑子。不妨设四个角都是黑子,这样染色后,黑子25个,白子23个,外加1的位置。

穿线的时候,必然是1黑1白1黑1白。25个黑子,23个白子,黑子比白子多2个,必然穿不起来。

证毕。

多3个显然穿不起来,多2个怎么证明?
[/Quote]
明白了。自己马虎。
rongzhou19831007 2009-05-13
  • 打赏
  • 举报
回复
学习中,期待求解
eatsweetpotato 2009-05-13
  • 打赏
  • 举报
回复
mark
lxh8810 2009-05-13
  • 打赏
  • 举报
回复
向17楼敬礼。
lxh8810 2009-05-13
  • 打赏
  • 举报
回复
当然不能Z型的啦 只能上下左右连
crst_zh 2009-05-13
  • 打赏
  • 举报
回复
接楼上的,我在一直考虑线段,就是没考虑到染色啊,向17楼致敬:)
crst_zh 2009-05-13
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 zhangyan_wt 的回复:]
无解。

将棋盘黑白相间染色,保证黑子上下左右都是白子,白子上下左右都是黑子。不妨设四个角都是黑子,这样染色后,黑子25个,白子23个,外加1的位置。

穿线的时候,必然是1黑1白1黑1白。25个黑子,23个白子,黑子比白子多2个,必然穿不起来。

证毕。
[/Quote]

这才是高手!
同样也证明:
3×3的无解 :5黑三白外加一个1
5×5的有解 :12黑12白,外加一个1
ddwindcat 2009-05-13
  • 打赏
  • 举报
回复
不能折起来么。。。

0 0
0 0
0 0
0 1
0 0
0 0
0 0

折起来就好画了。。。
zhangyan_wt 2009-05-13
  • 打赏
  • 举报
回复
无解。

将棋盘黑白相间染色,保证黑子上下左右都是白子,白子上下左右都是黑子。不妨设四个角都是黑子,这样染色后,黑子25个,白子23个,外加1的位置。

穿线的时候,必然是1黑1白1黑1白。25个黑子,23个白子,黑子比白子多2个,必然穿不起来。

证毕。

flora186 2009-05-13
  • 打赏
  • 举报
回复
牛人,顶!
duyouxuanduyouxuan 2009-05-13
  • 打赏
  • 举报
回复
Mark
gkicehebe 2009-05-13
  • 打赏
  • 举报
回复
好难啊 我是不会啊
liguiju 2009-05-13
  • 打赏
  • 举报
回复
可能是考察抽象、发散思维吧,个人的愚见,高手莫见笑
总路径由三条线组成:
1、1所在列位置的上面三个元素组成一条垂直的线(起始端从1上面的那个元素开始);
2、所有行的前六列看成抽象的垂直一条线(去除1所在的列);
3、1所在列位置的下面三个元素组成一条垂直的线(终端从1下面的那个元素结束);
4、整体形状是一个大写的字母“C”;
5、按照字母"C"的书写顺序划出整体的线条即完成;
6、起始端:1上面的那个元素,终端:1下面的那个元素;


这种题目如果是面试,不是笔试,一般简单陈述思想即可,若是笔试一般是程序实现算法;
勉励前行 2009-05-13
  • 打赏
  • 举报
回复
回头看,上面部分代码有错:
函数原型是这个:
int TResult::LineNext(TResult &Source , int &i,int &j , TResult &result) ;

有心人可以修正代码调试一下,主要是描述一种递归遍历问题空间的过程。
该问题解法类似于马步踏遍棋盘的问题。
勉励前行 2009-05-13
  • 打赏
  • 举报
回复
用一根曲线或者折线,就简单解决了。

如果直线只能两点相连而且线必须是水平或垂直的。可以尝试编程遍历来解决。

//定义矩阵问题原型及结果
struct TMyPoint //每个点
{
int value ; // 0 或 1
bool lined ; // 是否已画线
};
struct TLinePoint //连线点
{
int x ,y ;
TLinePoint(){} ;
TLinePoint(int a, int b) :x(a) , y(b) {}
};
class TResult
{
public :
TMyPoint Rec[7][7] ; //源矩阵
std::vector< TLinePoint > Lines ; //连线次序
bool OK ; //是否有解
int LineNext(TResult &r[7][7] , int &i,int &j); //递归求解
};

//结束条件:1为OK , 0 为未完成 , -1为失败。
int IsEnd(TMyPoint &r[7][7] )
{
for(int i = 0 ; i < 7 ; ++i)
for(int j = 0 ; j < 7 ; ++j)
if(r[i][j].value == 0 && !r[i][j].lined )
return 0 ;
else if(r[i][j].value == 1 && r[i][j].lined )
return -1 ;
return 1 ;
}

//(递归解法)
int TResult::LineNext(TResult &Source , int &i,int &j , TResult &result)
{
TResult tmp = Source ;
int a = i, b = j ;
if(i-1 > 0 && ! tmp.Rec[i-1][j].lined )//向左:
--a ;
else if(i+1 < 7 && ! tmp.Rec[i+1][j].lined )//向右:
++a ;
else if(j-1 > 0 && ! tmp.Rec[i][j-1].lined )//向上:
--b ;
else if(j+1 < 7 && ! tmp.Rec[i][j+1].lined )//向下:
++b ;
else
return -1 ;
tmp.Source[a][b].lined = true ;
tmp.Lines.push_back(TLinePoint(a,b)); //记录路线
switch(IsEnd(tmp))
{
case 1 ://得到正确路线
tmp.OK = true ;
result = tmp ;
return 1 ;
case -1: return -1; //失败
case 0 :
default: //未完成 , 继续画线
do{ int r = LineNext(r,i,j);//宽度搜索优先
if(r == 1 ) return 1 ;
}while( r != -1)
return LineNext(tmp,a,b); //向深度搜索
break ;
}
return 0 ;
}

//例子:
//初始化矩阵
TResult AA;
for(int i = 0 ; i < 7 ; ++i)
for(int j = 0 ; j < 7 ; ++j)
AA.rec[i][j].value = 0 ,AA.rec[i][j].lined = false ;
AA.rec[3][6].value = 1 ;
AA.OK = false ;
//从任意一点开始画线,并求解结果
for(int i = 0 ; i < 7 ; ++i)
for(int j = 0 ; j < 7 ; ++j)
if(AA.LineNext(AA,i,j,AA) == 1)
break ;
if(!AA.OK)
cout << "此题无解" ;
else
{
cout << "连线次序是:\n" :
std::vector< TLinePoint > ::iterator p = AA.Lines.begin();
for( ; p != AA.Lines.end() ; ++p)
cout << p->x <<","<<p->y <<"\n";
}
<注:以上代码一次写成未调试,如果出错,莫怪>
crst_zh 2009-05-13
  • 打赏
  • 举报
回复
3×3 无解
5×5 有解
7×7 无解


假设能连起来的话:
3×3,共9个点,其中1个为1,剩下8个要用一根线连起来的话,需要7条线段: 3×3-1-1
5×5,共25个点,其中1个为1,剩下24个要用一根线连起来的话,需要23条线段:5×5-1-1
7×7,共49个点,其中1个为1,剩下48个要用一根线连起来的话,需要47条线段:7×7-1-1

似乎可以证明的?期待高手:

3 5 7 9 11
7 23 47 79 119
ysysbaobei 2009-05-13
  • 打赏
  • 举报
回复
wanghao111 2009-05-13
  • 打赏
  • 举报
回复
好像有个手机游戏,与这个形式类似
nyhenry1 2009-05-13
  • 打赏
  • 举报
回复
这跟线得在1附近变细。。把1露出来。。
加载更多回复(10)

65,211

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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