说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

唉,郁闷呀,平时不注重算法的后果

编辑:说三道四文库 发布时间:2018-02-25 04:15
HTML文档下载 WORD文档下载 PDF文档下载
今天到一家公司去应聘,问过一些基础知识后,让我做一道题,关于算法的,我平常不注重算法,所以没有答上。真是郁闷呀。回家后一查原来是第五届全国青少年信息学(计算机)奥林匹克分区联赛普及组复赛试题中的一道。真晕。我都24了难道还是少年组的水平!!!!!唉,难受呀,一会饿补下算法的部份。
把题帖出来大家分享下吧,唉。

-------------------------------------------------------------
第一题 Cantor表(30分)
现代数学的著名证明之一是Georg Cantor证明了有理数是可枚举的。他是用下面这一张
表来证明这一命题的:
1/1  1/2  1/3  1/4  1/5 ...
2/1  2/2  2/3  2/4  ...
3/1  3/2  3/3  ...
4/1  4/2 ...
5/1
   我们以z字型给上表的每一项编号。第1项是1/1,然后是1/2,2/1,3/1,2/2...
输入:整数n(1<=n<=10)
输出:表中的第N项
样例:
input:  n=7
output: 1/4
大家都做下答案,我想看看有多少是和我在算法上是一个档次的。呵呵。
不懂,怎么算第七项会是1/4啊?
是这么排的
1  2  4  7 
3  5  8
6  9
10
所以第七项是1/4 
不过偶不知道这个题怎么做..
不会:((
不是了。顺序不对  应是这么排的,
1  2  6  7  15...
3  5  8  14 ...
4  9  13  ....
10 12  .....
11   ......
晕,哪有公司应聘马上就考你算法的啊,呵呵,你中头彩了。
呵呵~ 有是有,就是怎么也不会这么难吧!
其实这不是算法题,是数学题
不好意思 顺序排错了 :(
那个考官一眼就能看出来是个重能力不重文凭地。
我还没说他让我用任何语言print一个 ,唉。
     
     15  16  17  18  1
     14  27  28  19  2
     13  26  29  20  3 
     12  25  30  21  4
     11  24  23  22  5
     10  9    8  7   6
说下我的想法:
这是个算法的问题,确实应该用程序来枚举:
就像贪吃蛇前进一样,前进的起点是1/1(第一步),方向依次为:向右、左下、下、右、右上,并循环。其中向右、下每次只能走一步,向左下、右上走到边缘为止(分子或分母为1)。如此往复。照此编程,并设置需要的计数器变量,这样给定要走的步骤,就能知道所在的数值了。
这是个简单的编程枚举求值问题,大家给想复杂了,所以感觉不对了。
不知我的想法是否还可接受。。
procedure TForm1.Button1Click(Sender: TObject);
var
  i, j, k, n: integer;
begin
  i := 1;
  n := strtoint(edit1.Text);
  while true do
    if n > i then
    begin
      n := n - i;
      i := i + 1;
    end
    else
      break;
  if i mod 2 = 1 then
  begin                 {j/k}
    j := i + 1 -n;
    k := n;
  end
  else
  begin
    j := n;
    k := i + 1 - n;
  end;
  edit1.Text := inttostr(j) + '/' + inttostr(k);
end;
那位把答案做出来一下,让我开开壳呀,也不能让我死的这么怨吧。
搞得我一下午心情一直不好,唉呀呀。
初学,帮顶。
1/1  1/2  1/3  1/4  1/5 ...
2/1  2/2  2/3  2/4  ...
3/1  3/2  3/3  ...
4/1  4/2 ...
5/1


分开考虑分子和分母的变化
分子 (1) (1 2) (3 2 1) (1 2 3 4) (5 4 3 2 1) 
分母 (1) (2 1) (1 2 3) (4 3 2 1) (1 2 3 4 5)

看到规律了吧?写出他们关于 f(n)的函数就行了
char *Get(int n)
{
        char str[256];
        int i = sqrt(2*n);
        if(i*(i+1)>=2*n)i--;
        int j = n-(i+++1)*i++/2;
        if(i%2){
                i-=j;
                sprintf(str, "%d/%d", j, i);
        }
        else
        {
                i-=j;
                sprintf(str, "%d/%d", i, j);
        }
        return str;
}
pazee(耙子)的算法写出来的代码最短。
但偶觉得亦可的想法更能体现计算机解题的方法。
呵呵,一家之言
比不过中学生也没什么好奇怪的

那些中学生都是在中学时代主动对程序设计发生的兴趣,基本都是些智商很高的孩子,做这类题比不过也很正常,莫非楼主认为自己参加小学奥赛一定能获奖?在自己能力范围内做的最好就行了.

站在软件开发的高度,这么点简单的东西又算的了什么呢?不过开发软件掌握这么点简单的算法设计还是必须的.有了这么点基础,代码的条理性,逻辑性也会好多了.
符合计算机解题的方法就是把所有问题交给计算机去解决?那高斯的求和公式在今天就没有价值了?算法设计就是解决数学问题,符合计算机解题的方法就是让计算机用最少的时间得出结果.这里不存在大量数据,一般此类算法最优的结果就是时间复杂度最低.

代码简洁也不等于执行效率高,去看看真正高手写的算法,为了提高执行效率还要特意拆开循环,多写大量代码.就是细节的汇编优化,考虑到指令配对问题,还有人把1条指令拆成N条...
首先确定根据k(k+1)/2<n<(k+1)(k+2)/2可以确定k+1就是n所在的斜行号
再看k是奇数还是偶数确定是
首先根据k(k+1)/2<n+1<(k+1)(k+2)/2来确定k,K+1就是n所在的斜行号,u=n-k(k+1)/2+1,
再看k是奇数还是偶数确定是u/k还是(k-u)/k

四星妖怪?
上回在c版里看到了个五星的怪物头子。哈哈.
你的意见我接受,我知道在算法这方面差很多,马上就补冲自己。
表示感谢!
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘