清华大学暑假作业的一道题,请帮忙?

milkway 2001-07-20 09:17:59
在电话语音识别中需要识别电话号码,这需要识别0到9十个数字,而识别前首先需要训练这十个数字,请编写程序设计一个电话号码表,要求数字组数最少。其中:每一组数字都是八位 (例如:62781704),0到9十个数字中每两个数字之间至少连接一次(像62781707,其中出现了:6-2、2-7、7-8、8-1、1-7、7-0、0-7七个连接,7-0和0-7是不同的连接),每个数字在开头、结尾至少各出现一次(像62781707,其中6在开头出现一次,7在结尾出现一次)。

我不会,高手们帮帮忙呀.
...全文
496 点赞 收藏 67
写回复
67 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
huahao0672 2001-08-13
我现在奉劝布我的最新答案。
01020304
05162738
12131415
23242526
49506172
34353637
45464748
56575859
67686960
78797071
89808182
83945658
90919293
共十三组答案。我想这应该就是最后的结果。请大家仔细的检查一下,看看有没有错误。
特别要指出的是倒数第二组的电话号码的的四位是随意加的。这是可以理解的,在十三组的电话号码当中,一定要有几组成重复的。没有一个重复是不可能的。
回复
huahao0672 2001-08-13
如果你的电话号码是十二组的话,那么一组电话号码共有七个连接。也就是说如果没有重复的话,最多只有八十四个连接这显然是错误的。因为,要使一个连接也不漏的话要有九十个连接。从一到一百当中除去十位和个位都相同的数共有九十个。比如说:“11,22,33、、、、99“这些都是应该除去的。我认为最少应该是十三组。13*7=91这才是最合理的。
回复
huahao0672 2001-08-13
microhard(涯) 请把你的作答案公布好吗???
回复
huahao0672 2001-08-13
我以前的公布的电话号码都是错误的。
现在公布我的最新的排列的电话号码。共有十三组,13*7=91也就是说要满足题目的要求应该有十三组电话号码。只有最后一个连接是重复的。总共就重复了一次。这是满足题目的要求的。
01020304
12131415
23242526
34353637
45464748
56575859
67686960
78797071
89808182
90919293
05162738
84950617
7283940
细心的人可能会发现最后一个电话是7位的。这就对了,这就说明整排列的号码中只有一个电话号码是重复的。
在我以前公布的程序当中有一些小错误,但不是很严重的。得到以上结果的程序与以前的程序相差不是很大。 有心者可自已研究一下。


回复
huahao0672 2001-08-13
microhard(涯) 能留一个地址吗,我们来聊聊
回复
huahao0672 2001-08-13
我已经找到正确的答案了,我是以提问的方式给出的。
回复
microhard 2001-08-13
坏了,最后一组的最后一位应该是9
回复
microhard 2001-08-13
我的解肯定不是最优,重复的太多了
回复
microhard 2001-08-13
我犯了一个愚蠢的错误.忘记最优解的个数>=13.
但是你的解少了,28,84,40这三对.第二组最后4位好像不是随意加的,因为少了他们,解就不对了,后4位好像是人为加的.
我的解是14个.
01234567
78902135
46579803
14253681
97041524
37691826
50638472
29305160
87492071
61943108
58327540
62859648
09517398
86444440
回复
huahao0672 2001-08-12
上面的程序我忘了写一个循环链表。*s
对上面的老兄,我想你可以计算一下满足题目要求的电话码数是多少。这是可以计算出来的。你可以再好好研究一下。我下面给出数结在计算机中的真实表
示 。
*head[0]->0102030405060708
*head[1]->1213141516171819
*head[2]->2324252627282920
*head[3]->3435363738393031
*head[4]->4546474849404142
*head[5]->5657585950515253
*head[6]->6768696061626364
*head[7]->7879707172737475
*head[8]->8980818283848586
*head[9]->9091929394959697
上面的这位老兄,你以列为序在看看你个链表没有一个重复的也没有一个多余的取电话号码时,以每行的前八个和后八个来取,就是我们要求的结果。这与我一开始的计算是吻合的。
如果你觉得有什么不对我们可以在讨论讨论。
回复
microhard 2001-08-12
如果"0到9十个数字中每两个数字之间至少连接一次,那么相同的数就不应该再连接"成立,
我的解只有12组号码.
回复
huahao0672 2001-08-12
我对这道的的理解可能会有的人不同,我认为题目中要求"0到9十个数字中每两个数字之间至少连接一次"那么相同的数就不应该再连接。如果那样的话就浪费一次连接,号码一定不是最少。所以最后电话号码中就不能出现相同的号码连在一起。
不知大家是不是同意我的看法。
回复
huahao0672 2001-08-12
我有解当中重复的是太多了。我仔细的想了想。出错的原因在于链表的列数没有控制好。
不是十六列而是十二列为什么呢?因为到了十二列的时候民经开始重合。我是指号码数不知你是不是能懂我的意思。比如说,0102、、、下面是从9080、、、按照这样算来只需要十二列。
新的程序如下:
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{int data;
struct node *next;
}
node *s;
main()
{node *head[10],*p,*la;
int i,j,judge,r;
s=malloc(sizeof(node));/*初始化一个循环链表的表头*/
s->next=s;
la=s;
for(i=0,i<10;i++)
{head[i]=malloc(sizeof(node));
head->next=null;
}
for(i=0,i<10;i++)
{p=malloc(sizeof(node));
p->next=la->next;
p->data=i;
la->next=p;
la=la->next;
}
for(i=1;i<13;i++)
{ if(i%2==0) judge=0;
else judge=1;
for(j=0;j<10;j++)
{if(judge==0)
{la=last_node(head[j]);
p=malloc(sizeof(node));
p->next=la->next;
p->data=j;
}
else
{la=last_node(head[j]);
p=malloc(sizeof(node));
p->next=la->next;
la->next=p;
p->data=s->next->next;
s=s->next->next;
}
}
}
for(i=0;i<10;i++)
{p=head[i]->next;
for(j=1;j<13;j++)
{printf("%d",p->data);
p=p->next;
if(j==8) printf(",\n");
}
if((i+1)%2!=0)
{ p=head[i+1]->next;
for(j=1;j<13;j++)
{if(j<=8) continue;
else
{printf("%d",p->data);
p=->next;
}
}
printf("\n");
}
}
}
node last_node(*l)
{node *p;
int i,j;
whlie(l!=null)
l=l->next;
return l;
}
执行以上的程序的结果如下:
01020304
05061617
12131415
23242526
27283839
34353637
45464748
49405051
56575859
67686960
61627273
78797071
89808182
83849495
90919293
这样一来共有十五组电话号码。大家来检查一下看看有没有重复的。



回复
microhard 2001-08-12
你的解当中重复的太多了。我想你的解不是最优的
回复
microhard 2001-08-12
to huahao0672(华好0672)
可是题目并没要求不许重,题目要求不许漏,而且号码数量最少。你怎么保证你的解是最优的。
回复
microhard 2001-08-11
to huahao0672(华好0672):
咱们讨论讨论吧。你做出结果可能覆盖所有测试点,但是你的电话组数,好像太多了。
题目要求组数最少。
回复
huahao0672 2001-08-11
这个问题是非常简单的。关键在于你是如何考虑的看了。上面各位仁兄的分析觉得一定要说一下。
它要求各个数字至少出现在各个电话号码中的首尾各一次抓住这一点就行了。它说明这个问题对列有要求。我的思路来了。建立1个指针数组*herd[10],由此而产生10个链表。然后建立一个循环链表其中供有十个结点,其权值是按顺序从一到十。这10链表的头结点是一到十,然后先调用循环链表再用一个一到十的正常顺序的数值写到中间去,问题就解决了。程序如下:
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{int data;
struct node *next;
}
node *s;
main()
{node *head[10],*p;
int i,j,judge;
for(i=0,i<10;i++)
{head[i]=malloc(sizeof(node));
head->next=null;
}
for(i=1;i<=16;i++)
{ if(i%2==0) judge=0;
else judge=1;
for(j=0;j<10;j++)
{if(judge==0)
{la=last_node(head[j]);
p=malloc(sizeof(node));
p->next=la->next;
p->data=j;
}
else
{la=last_node(head[j]);
p=malloc(sizeof(node));
p->next=la->next;
la->next=p;
p->data=s->next->next;
s=s->next->next;
}
}
}
for(i=0;i<10;i++)
{p=head[i]->next;
for(j=1;j<=16;j++)
{printf("%d",p-data);
p=p->next;
if(j==8) printf(",\n");
}
printf("\n");
}
}
node last_node(*l)
{node *p;
int i,j;
whlie(l!=null)
l=l->next;
return l;
}
最后的结果是:
01020304
05060708
12131415
16171819
23242526
27282920
34353637
38393031
45464748
49404142
56575859
50515253
67686960
61626364
78797071
72737475
89808182
83848586
90919293
94959697
共二十组答案,仔细观察的确如此说明程序是正确的。




回复
eWolf 2001-08-08


62781704是你的电话吗?

回复
milkway 2001-08-07
加分啦
回复
milkway 2001-08-07
感谢呀.
回复
加载更多回复
相关推荐
发帖
数据结构与算法
创建于2007-08-27

3.2w+

社区成员

数据结构与算法相关内容讨论专区
申请成为版主
帖子事件
创建了帖子
2001-07-20 09:17
社区公告
暂无公告