{面试}{技术}一道简单的二维数组面试题

150 views
Skip to first unread message

Shuo Chen

unread,
Dec 27, 2009, 10:30:14 PM12/27/09
to TopLanguage
年底了,轻松一下。

http://www.javaeye.com/topic/545378?page=1

一个画图程序 要求打印出

int i=5;
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9

int i=6
1 2 3 4 5 6
20 21 22 23 24 7
19 32 33 34 25 8
18 31 36 35 26 9
17 30 29 28 27 10
16 15 14 13 12 11

我这里加一个限制,i<=25。

题目很简单,大一学生分分钟就能写出来。
语言不限,常规语言都行,C/C++/Java/C#/Ruby/Python/Perl。
代码简洁易懂为佳。(这里算是一个反例: http://www.javaeye.com/topic/557924
请各路高手各显神通,我会在第10楼贴出自己的C程序。

Tinyfool

unread,
Dec 27, 2009, 10:42:59 PM12/27/09
to pon...@googlegroups.com
把这个骗答案的大学生打出去…

玩笑,好麻烦,懒得想



--
Tinyfool的开发日记 http://www.tinydust.net/dev/
代码中国网 http://www.codechina.org
myTwitter: http://twitter.com/tinyfool

Simon Liu

unread,
Dec 27, 2009, 11:08:08 PM12/27/09
to pon...@googlegroups.com
参考答案让我想起了八股文

2009/12/28 Tinyfool <tiny...@gmail.com>



--
Simon Liu
Email/MSN/GTalk: yuntao.liu#gmail.com

sagasw

unread,
Dec 28, 2009, 12:38:43 AM12/28/09
to pon...@googlegroups.com
使用了Lua代码,未必简单,但是还算易懂吧,思路想的比较快(四个状态互相切换),但是写出来就慢了不少。
总体花了大概快一个小时的时间编写调试。

local currentCount = 1
local limitNum = 5
local currentLevel = 0
local result = {}

function AddY(x, y)
    if currentCount > limitNum * limitNum then
        return
    else
        if y > (limitNum - currentLevel) then
            return AddX(x + 1, y - 1)
        end

        print("addY", x, y, "current:" .. currentCount)
        result[(x -1)* limitNum + y] = currentCount
        currentCount = currentCount + 1

        y = y + 1
        return AddY(x, y)
    end
end

function AddX(x, y)
    if currentCount > limitNum * limitNum then
        return
    else
        if x > (limitNum - currentLevel) then
            return MinusY(x - 1, y - 1)
        end

        print("addX", x, y, "current:" .. currentCount)
        result[(x -1)* limitNum + y] = currentCount
        currentCount = currentCount + 1

        x = x + 1
        return AddX(x, y)
    end
end

function MinusY(x, y)
    if currentCount > limitNum * limitNum then
        return
    else
        if y < (1 + currentLevel) then
            currentLevel = currentLevel + 1
            return MinusX(x -1, y + 1)
        end

        print("MinuxY", x, y, "current:" .. currentCount)
        result[(x -1)* limitNum + y] = currentCount
        currentCount = currentCount + 1

        y = y - 1
        return MinusY(x, y)
    end
end


function MinusX(x, y)
    if currentCount > limitNum * limitNum then
        return
    else
        if x < (1 + currentLevel) then
            return AddY(x + 1, y + 1)
        end

        print("MinuxX", x, y, "current:" .. currentCount)
        result[(x -1)* limitNum + y] = currentCount
        currentCount = currentCount + 1

        x = x - 1
        return MinusX(x, y)
    end
end

AddY(1, 1)

-- print result
for i = 1, limitNum do
    local linestr = ""
    for j = 1, limitNum do
        linestr = linestr .. "    " .. result[(i -1) * limitNum + j]
    end
    print(linestr)
end


------------------------------------
C++, Lua, living in Dalian
http://sunxiunan.com/
http://twitter.com/sagasw
------------------------------------


2009/12/28 Shuo Chen <gian...@gmail.com>

翔李

unread,
Dec 28, 2009, 12:27:24 AM12/28/09
to pon...@googlegroups.com
一个回形图。。。



2009/12/28 Simon Liu <yunta...@gmail.com>

Shuo Chen

unread,
Dec 28, 2009, 1:18:11 AM12/28/09
to TopLanguage
感觉好像四个函数在相互调用,就像转圈一样。

> C++, Lua, living in Dalianhttp://sunxiunan.com/http://twitter.com/sagasw
> ------------------------------------
>
> 2009/12/28 Shuo Chen <giantc...@gmail.com>

Dbger

unread,
Dec 28, 2009, 1:25:05 AM12/28/09
to pon...@googlegroups.com
用C实现了一下,原理很简单,就是按照其规律不停的变换方向与始末的index即可:

// PrintNum.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>

#define MAXNUM  25
int arr[MAXNUM][MAXNUM];

int _tmain(int argc, _TCHAR* argv[])
{

    int num = 6; // argv[1]; this is the value you need to input

    int startX = 0;
    int endX = num - 1;
    int startY = 0;
    int endY = num - 1;

    bool dir_increase = true;

    int value = 0;
    while (value != num * num)
    {
        // fill the rows
        if(dir_increase)
        {
            for (int i = startX; i <= endX; i++)
            {
                arr[startY][i] = ++value;
            }

            startY++;
        }
        else
        {
            for (int i = endX; i >= startX; i--)
            {
                arr[endY][i] = ++value;
            }
            endY--;
        }

        // fill the columns
        if (dir_increase)
        {
            for (int j = startY; j <= endY; j++)
            {
                arr[j][endX] = ++value;
            }
            endX--;
        }
        else
        {
            for (int j = endY; j >= startY; j--)
            {
                arr[j][startX] = ++value;
            }
            startX++;
        }
        dir_increase = !dir_increase;
    }

    //print the final value
    for (int i = 0; i < num; i++)
    {
        for (int j = 0; j < num; j++)
        {
            printf("%2d ", arr[i][j]);
        }
        printf("\n");
    }
    system("pause");
    return 0;
}




技术博客:http://debuggingnow.com
我的豆瓣:http://www.douban.com/people/baiyanhuang/


2009/12/28 sagasw <sag...@gmail.com>

Dbger

unread,
Dec 28, 2009, 1:30:56 AM12/28/09
to pon...@googlegroups.com
上次做这种题目应该是8年前了~~~
花了大概半个小时,权当怀旧一把~~~~
2009/12/28 Dbger <baiya...@gmail.com>

sagasw

unread,
Dec 28, 2009, 1:35:10 AM12/28/09
to pon...@googlegroups.com
没错,其实就是4种状态的互相切换,当然像是转圈。
代码理解起来要容易一些。


------------------------------------
C++, Lua, living in Dalian
http://sunxiunan.com/
http://twitter.com/sagasw
------------------------------------


2009/12/28 Shuo Chen <gian...@gmail.com>

Dbger

unread,
Dec 28, 2009, 1:38:04 AM12/28/09
to pon...@googlegroups.com
@sagasw 呵呵,本来就是在转圈嘛
lua没怎么用过,在云风的blog里看他对lua相当推崇,你们平时工作中主要用lua做些什么的?
2009/12/28 sagasw <sag...@gmail.com>
没错,其实就是4种状态的互相切换,当然像是转圈。

Shuo Chen

unread,
Dec 28, 2009, 1:39:04 AM12/28/09
to TopLanguage
不错,相当于分为上下两个半周期来做,每次循环填一半(上右或者下左),然后变号。
唯 {start,end}{X,Y} 这四个变量的变化有点眼晕。

> > 2009/12/28 Shuo Chen <giantc...@gmail.com>

sagasw

unread,
Dec 28, 2009, 1:41:35 AM12/28/09
to pon...@googlegroups.com
我个人使用它做一些重复性的小应用程序,就跟用python或者ruby一样。


------------------------------------
C++, Lua, living in Dalian
http://sunxiunan.com/
http://twitter.com/sagasw
------------------------------------


2009/12/28 Dbger <baiya...@gmail.com>

Dbger

unread,
Dec 28, 2009, 1:43:30 AM12/28/09
to pon...@googlegroups.com
这四个变量用来控制每个循环的始末点,就是每填一行或者一列都要调整以适合下一个循环,结合你列出的实例来读会比较好一点。
2009/12/28 Shuo Chen <gian...@gmail.com>

Mikster.Z

unread,
Dec 28, 2009, 1:44:28 AM12/28/09
to pon...@googlegroups.com
faint,要说写的通俗易懂些,还是dfs,自己走的好~~不就是后下前上嘛~~~

2009/12/28 sagasw <sag...@gmail.com>



--
EX - EMBEDDED SYSTEM DEVELOPER
SOFTWARE ENGINEER
Name : Mikster  

Dbger

unread,
Dec 28, 2009, 1:44:27 AM12/28/09
to pon...@googlegroups.com
了解,这方面我perl用的比较多些,对正则表达式的支持相当强大。

sagasw

unread,
Dec 28, 2009, 1:52:07 AM12/28/09
to pon...@googlegroups.com
拭目以待!


------------------------------------
C++, Lua, living in Dalian
http://sunxiunan.com/
http://twitter.com/sagasw
------------------------------------


2009/12/28 Mikster.Z <china...@gmail.com>

Jeffrey Zhao

unread,
Dec 28, 2009, 1:53:03 AM12/28/09
to pon...@googlegroups.com
如果是Win下工作的兄弟,我建议可以买一个RegexBuddy用,很值。
 
 

Tinyfool

unread,
Dec 28, 2009, 1:54:36 AM12/28/09
to pon...@googlegroups.com
跑题跑过分了吧?

2009/12/28 Jeffrey Zhao <je...@live.com>

jun lin

unread,
Dec 28, 2009, 1:58:53 AM12/28/09
to pon...@googlegroups.com
写了我半个小时,调OK了:
python实现:

DIRECTS = LEFT,TOP,RIGHT,DOWN = 0,1,2,3

def evalNext(pos,direct):
    #caculate next
    if   direct == LEFT:
        next = pos[0]-1, pos[1]
    elif direct == TOP:
        next = pos[0]  , pos[1]-1
    elif direct == RIGHT:
        next = pos[0]+1, pos[1]
    elif direct == DOWN:
        next = pos[0]  , pos[1]+1
    else:
        raise Exception("direct error:",direct)
    return next

def step(matrix, number, next, i):
    #check out of range
    if next[0]>=number or next[0]<0:
        return
    if next[1]>=number or next[1]<0:
        return

    #check next number have value
    if matrix[next[1]] [next[0]] != 0:
        return

    #set value
    matrix[next[1]] [next[0]] = i
    print next
    return True

def createM(number):
    matrix = [[0 for i in range(number)]
              for i in range(number)]
    direct = RIGHT
    pos = (-1,0)
    i = 1
    END = False
    while not END:
        next = evalNext(pos, direct)
        steped = step(matrix,number,next,i)
        if not steped:
            if pre_steped:
                break #end
            #move to next direction
            direct += 1
            direct %= 4
            pre_steped = True
            print "direct to:",direct,pos
        else:
            pos = next
            i += 1
            pre_steped = False
    #print matrix
    for line in matrix:
        print ",".join(
            ["%.3d"%i for i in line])

def main():
    createM(12)

if __name__=="__main__":
    main()


2009/12/28 Tinyfool <tiny...@gmail.com>

ChenMing

unread,
Dec 28, 2009, 1:58:57 AM12/28/09
to pon...@googlegroups.com
不是要求只求小于25的解吗。那可以直接先把答案写好,然后查表打印出结果就OK了。纯粹体力活...


2009/12/28 Mikster.Z <china...@gmail.com>:

--
Regards.
Chen Ming

Mikster.Z

unread,
Dec 28, 2009, 2:07:02 AM12/28/09
to pon...@googlegroups.com
不晓得你是什么意思......
void
dfs(int k)
{
  if (k > m * m)
    {

      return;
    }
  if (available(x, y + 1))
    {
      matrix[x][++y] = k;
    }
  else if (available(x + 1, y))
    {
      matrix[++x][y] = k;

    }
  else if (available(x, y - 1))
    {
      matrix[x][--y] = k;
    }
  else if (available(x - 1, y))
    {
      matrix[--x][y] = k;
    }

  else
    {
      return;
    }

  dfs(k + 1);
}
傻帽是傻帽了点,简洁易懂应该是有吧....撞墙就左转嘛~

2009/12/28 sagasw <sag...@gmail.com>

Mikster.Z

unread,
Dec 28, 2009, 2:07:58 AM12/28/09
to pon...@googlegroups.com
25以内写好答案这个体力活还不如敲点代码....

2009/12/28 ChenMing <mocke...@gmail.com>

Mikster.Z

unread,
Dec 28, 2009, 2:18:01 AM12/28/09
to pon...@googlegroups.com
貌似顺序有点儿反~~:(

2009/12/28 Mikster.Z <china...@gmail.com>

Shuo Chen

unread,
Dec 28, 2009, 2:18:06 AM12/28/09
to TopLanguage
嗯,这个是小老鼠转迷宫的算法。

唯pos[0]和pos[1] , matrix[next[1]] [next[0]] 有些费解。
pos[0] 应该是 x 坐标吧。那么 matrix[][] 是先列后行?

> 2009/12/28 Tinyfool <tinyf...@gmail.com>


>
> > 跑题跑过分了吧?
>
> > 2009/12/28 Jeffrey Zhao <je...@live.com>
>
> > 如果是Win下工作的兄弟,我建议可以买一个RegexBuddy用,很值。
>
> >> Jeffrey Zhao
> >> Blog:http://www.cnblogs.com/JeffreyZhao/
> >> Twitter:https://twitter.com/jeffz_cn
>

> >> *From:* Dbger <baiyanhu...@gmail.com>
> >> *Sent:* Monday, December 28, 2009 2:44 PM
> >> *To:* pon...@googlegroups.com
> >> *Subject:* Re: [TL] Re: {面试}{技术}一道简单的二维数组面试题


>
> >> 了解,这方面我perl用的比较多些,对正则表达式的支持相当强大。
>
> >> 技术博客:http://debuggingnow.com
> >> 我的豆瓣:http://www.douban.com/people/baiyanhuang/
>
> >> 2009/12/28 sagasw <sag...@gmail.com>
>
> >>> 我个人使用它做一些重复性的小应用程序,就跟用python或者ruby一样。
>
> >>> ------------------------------------
> >>> C++, Lua, living in Dalian
> >>>http://sunxiunan.com/
> >>>http://twitter.com/sagasw
> >>> ------------------------------------
>

> >>> 2009/12/28 Dbger <baiyanhu...@gmail.com>


>
> >>> @sagasw 呵呵,本来就是在转圈嘛
> >>>> lua没怎么用过,在云风的blog里看他对lua相当推崇,你们平时工作中主要用lua做些什么的?
>
> >>>> 技术博客:http://debuggingnow.com
> >>>> 我的豆瓣:http://www.douban.com/people/baiyanhuang/
>
> >>>> 2009/12/28 sagasw <sag...@gmail.com>
>
> >>>>> 没错,其实就是4种状态的互相切换,当然像是转圈。
>
> >>>>> 代码理解起来要容易一些。
>
> >>>>> ------------------------------------
> >>>>> C++, Lua, living in Dalian
> >>>>>http://sunxiunan.com/
> >>>>>http://twitter.com/sagasw
> >>>>> ------------------------------------
>

> >>>>> 2009/12/28 Shuo Chen <giantc...@gmail.com>

> >>>>>> > C++, Lua, living in Dalianhttp://
> >>>>>> sunxiunan.com/http://twitter.com/sagasw
> >>>>>> > ------------------------------------
>

Mikster.Z

unread,
Dec 28, 2009, 2:19:01 AM12/28/09
to pon...@googlegroups.com
跑了下发现是错的~~~ =。=

2009/12/28 Mikster.Z <china...@gmail.com>

Kenny Yuan

unread,
Dec 28, 2009, 2:18:45 AM12/28/09
to pon...@googlegroups.com
-1 -1 -1 -1 -1 -1 -1
-1 01 02 00 00 00 -1
-1 00 00 00 00 00 -1
-1 00 00 00 00 00 -1
-1 00 00 00 00 00 -1
-1 00 00 00 00 00 -1
-1 -1 -1 -1 -1 -1 -1



数据这样生成,然后就去大胆地撞吧

男人撞吧撞吧不是罪……


-1 -1 -1 -1 -1 -1 -1
-1 01 02 03 04 05 -1
-1 16 17 18 19 06 -1
-1 15 24 25 20 07 -1
-1 14 23 22 21 08 -1
-1 13 12 11 10 09 -1
-1 -1 -1 -1 -1 -1 -1

撞到灌满了为止!


--
Kenny Yuan
C++, UI, LISP, MMA, Psychology and Automobile.
BLOG: CS巴别塔(Computer Science Babel)
URL1: http://csbabel.wordpress.com/
URL2: http://blog.csdn.net/yuankaining/

Mikster.Z

unread,
Dec 28, 2009, 2:22:07 AM12/28/09
to pon...@googlegroups.com
就是贼个意思,but俺实现错鸟~~~等着挨砖呢~
-1边界可以去掉了~~撞墙向左转!

2009/12/28 Kenny Yuan <yuank...@gmail.com>

jun lin

unread,
Dec 28, 2009, 2:27:35 AM12/28/09
to pon...@googlegroups.com
没人看我的代码吗?

2009/12/28 Mikster.Z <china...@gmail.com>

Mikster.Z

unread,
Dec 28, 2009, 2:42:04 AM12/28/09
to pon...@googlegroups.com
int x = 0, y = 0;
int m = 0;
int matrix[100][100];
int dir[4][2] ={{0,1},{1,0},{0,-1},{-1,0}};
int oldir = 0;
void
available(int a, int b)
{
  int tx = a+dir[oldir][0];
  int ty = b+dir[oldir][1];
  if(matrix[tx][ty] != 0 || tx < 0 || ty < 0 || tx >= m || ty >= m)
      oldir= (oldir+1)%4;
// whatever 一次转身足以卸下所有的负累
  x = a+dir[oldir][0];
  y = b+dir[oldir][1];
}
void
dfs(int k)
{
  if (k > m * m)
    {
      return;
    }
  available(x,y);
  matrix[x][y]=k;
  dfs(k + 1);
}
 !不要唾弃和鄙视我,我只是纠正下我的错误~~

2009/12/28 jun lin <linjun...@gmail.com>

Jacky, Z

unread,
Dec 28, 2009, 3:02:43 AM12/28/09
to pon...@googlegroups.com
下面是我的解法,特点是只要4个int的空间。
好吧,其实可以只留下两个用于循环的变量i,j。。
再进一步,只留下一个循环变量就可以了。。。
//-----------------------------------------------------------
#include <iostream>
#include <iomanip>
using namespace std;

int circle_matrix(int n) {
    if (n <= 0)
        return -1;
    int a, b;
    for (int i=0; i < n; ++i) {
        if(i > (n-1)/2) {
            a = (n-1) - i;
        } else
            a = i;
        for    (int j=0; j < n; ++j) {
            if(j > (n-1)/2) {
                b = (n-1) - j;
            } else
                b = i;
            if (a <= b) {
                if (i == a) {
                    cout << setw(4) << 1-4*(a+1)*a+a*(4*n+4) + (j-a);
                } else
                    cout << setw(4) << 1-4*(a+1)*a+a*(4*n+4) + (n-2*a-1)*2 + (n-a-1-j);
            } else {
                if (j != b) {
                    cout << setw(4) << 1-4*(b+1)*b+b*(4*n+4) + (n-2*b-1) + (i-b);
                } else
                    cout << setw(4) << 1-4*(b+1)*b+b*(4*n+4) + (n-2*b-1)*3 + (n-b-1-i);
            }
        }
        cout << endl;
    }
    return 0;
}

int main() {
    circle_matrix(5);
    return 0;
}

2009/12/28 Shuo Chen <gian...@gmail.com>

Shuo Chen

unread,
Dec 28, 2009, 3:11:34 AM12/28/09
to TopLanguage
好,分段公式法。

果然各路神仙各显神通。

> 2009/12/28 Shuo Chen <giantc...@gmail.com>

Shuo Chen

unread,
Dec 28, 2009, 3:35:26 AM12/28/09
to TopLanguage
把我自己的贴一下,C 写的,非递归版。

#include <stdio.h>
#include <stdlib.h>

int maze[25][25];

int fill(int start, int left, int up, int right, int down)
{
int now = start;
for (int i = left; i < right; ++i)
maze[i][up] = now++;
for (int i = up; i < down; ++i)
maze[right][i] = now++;
for (int i = right; i > left; --i)
maze[i][down] = now++;
for (int i = down; i > up; --i)
maze[left][i] = now++;
return now;
}

int main(int argc, char* argv[])
{
int N = atoi(argv[1]);
int start = 1;
int left = 0, right = N-1, up = 0, down = N-1;

for (int i = 0; i < N/2; ++i) {
start = fill(start, left, up, right, down);
++left, --right, ++up, --down;
}

if (N % 2 == 1)
maze[left][up] = start;

for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
printf("%*d ", N < 10 ? 2 : 3, maze[j][i]);
}
printf("\n");
}
}

欢迎批评。

Pan

unread,
Dec 28, 2009, 4:55:44 AM12/28/09
to TopLanguage
花了点时间,用java实现了这个顺时针螺旋矩阵,不过变量命名挺不规范的,明天要考Heat Transfer,好无奈:

import java.lang.Math;
class practise {
public static void main(String[] arguments) {
for(int cycle = 5;cycle < 26;cycle++) {
int i,j;
int[][] matrix = new int[cycle][cycle];
int shangxian = cycle - 1;
matrix[0][0] = 1;
int kaishi,jieshu,jishu,flag;
jishu = 1;
for(int xunhuan = cycle - 1; xunhuan > 2; xunhuan--){
flag = Math.abs(xunhuan - shangxian);
kaishi = Math.abs(shangxian - xunhuan);
i = flag;

for ( j = kaishi; j < xunhuan + 1;j++){
matrix[i][j] = jishu;
jishu++;
}
jishu--;
j--;
for ( i = kaishi; i < xunhuan + 1;i++){
matrix[i][j] = jishu;
jishu++;
}
jishu--;
flag = Math.abs(flag - shangxian);
i = flag;
for ( j = flag ; j > kaishi;j--){
matrix[i][j] = jishu;
jishu++;
}
for ( i = flag; i > kaishi ;i--){
matrix[i][j] = jishu;
jishu++;
}
}
matrix[cycle/2][cycle/2] = cycle*cycle;
System.out.println("int = " + cycle);
for(i = 0; i < cycle; i++){
for(j = 0;j < cycle;j ++){
System.out.print(matrix[i][j] + " ");
}
System.out.print("\n");
}
System.out.println();

小黑

unread,
Dec 28, 2009, 6:42:31 AM12/28/09
to pon...@googlegroups.com
用C实现的。在大学时遇到过这个
#include<stdio.h>

#define MAX 20
int main(void)
{
    int i,j,k,x=0;
    int n,N;
    int direct = 0;    // direct为0表示向下移动,为1表示向上移动
    int m[MAX][MAX];

    scanf("%d",&n);
    j = 0;
    i = -1;
    k = 0;
    N = n*n;

    while( k < N )
    {
        switch(direct)
        {
        case 0:    // 向下
            while( i < n-1-x )
                m[++i][j] = ++k;
              break;
        case 1:    // 向右
            while( j < n-1-x )
                m[i][++j] = ++k;
             break;
        case 2:    //向上
            while ( i > x )
                m[--i][j]=++k;
            break;
        case 3:   //向左
            while ( j > x )
                m[i][--j]=++k;
            break;
        }
        if( direct == 3 )
        {
            direct=-1;
        }
        if(direct == 2 )
        {
            x++;
        }
        direct = direct+1;
    }
    for(i=0; i<n; ++i)
    {
        for(j=0; j<n; ++j)
            printf("%4d", m[i][j]);
        printf("\n");
    }
    return 1;
}

Alecs King

unread,
Dec 28, 2009, 6:54:37 AM12/28/09
to pon...@googlegroups.com
On Sun, Dec 27, 2009 at 07:30:14PM -0800, Shuo Chen wrote:
> 年底了,轻松一下。
>
> http://www.javaeye.com/topic/545378?page=1
>
> 一个画图程序 要求打印出
>
> int i=5;
> 1 2 3 4 5
> 16 17 18 19 6
> 15 24 25 20 7
> 14 23 22 21 8
> 13 12 11 10 9
>
> int i=6
> 1 2 3 4 5 6
> 20 21 22 23 24 7
> 19 32 33 34 25 8
> 18 31 36 35 26 9
> 17 30 29 28 27 10
> 16 15 14 13 12 11
>
> 我这里加一个限制,i<=25。

fill in the blanks:

---------------------------8<------------------------------
#include <cstdio>
#include <cstdlib>

// right, down, left, up
static const int dir[4][2] = {{0,1}, {1,0}, {0,-1},{-1,0}};

static int matrix[26][26];

int
main(int argc, char *argv[])
{

int n = 3;
if (argc == 2)
n = atoi(argv[1]);
// fill
for (int i = 1, r = 0, c = 0, d = 0; i <= n * n; i++) {
matrix[r][c] = i;
int nr = r + dir[d][0], nc = c + dir[d][1];
if (nr < 0 || nr >= n || nc < 0 || nc >= n || matrix[nr][nc]) {
d = (d+1) % 4;
nr = r + dir[d][0], nc = c + dir[d][1];
}
r = nr;
c = nc;
}
// print
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
printf("%3d%c", matrix[i][j], j == n - 1 ? '\n' : ' ');
return 0;
}
--------------------------->8------------------------------

or construct it recursively:

---------------------------8<------------------------------
import Text.Printf
import Data.Array

f 0 = []
f 1 = [((1,1),1)]
f n = up ++ right ++ bottom ++ left ++ inner
where up = [((1,i),i) | i <- [1..n]]
right = [((i,n),n+i-1) | i <- [2..n-1]]
bottom = [((n,i),n-i+2*n-1) | i <- [n,n-1..1]]
left = [((i,1),n-i+3*n-2) | i <- [n-1,n-2..2]]
inner = map (\((r,c), x) -> ((r+1,c+1), x+4*n-4)) . f $ n - 2

get n = array ((1,1),(n,n)) $ f n

format :: Int -> String
format n = unlines $ map row [1..n]
where row r = concatMap (\c -> printf "%4d" $ a ! (r, c)) [1..n]
a = get n

main = mapM_ (\n -> putStr $ format n ++ "\n\n") [1..10]
--------------------------->8------------------------------


--
Alecs King

sagasw

unread,
Dec 28, 2009, 7:29:20 AM12/28/09
to pon...@googlegroups.com
i < 25 这个限制有什么用?



------------------------------------
C++, Lua, living in Dalian
http://sunxiunan.com/
http://twitter.com/sagasw
------------------------------------


2009/12/28 Shuo Chen <gian...@gmail.com>
年底了,轻松一下。


http://www.javaeye.com/topic/545378?page=1

一个画图程序 要求打印出

int i=5;
 1  2  3  4  5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9

int i=6
 1  2  3  4  5   6
20 21 22 23 24  7
19 32 33 34 25  8
18 31 36 35 26  9
17 30 29 28 27 10
16 15 14 13 12 11

我这里加一个限制,i<=25。

Shuo Chen

unread,
Dec 28, 2009, 8:06:20 AM12/28/09
to TopLanguage
屏幕一行80列。

On Dec 28, 8:29 pm, sagasw <sag...@gmail.com> wrote:
> i < 25 这个限制有什么用?
>
> ------------------------------------

> C++, Lua, living in Dalianhttp://sunxiunan.com/http://twitter.com/sagasw
> ------------------------------------
>
> 2009/12/28 Shuo Chen <giantc...@gmail.com>

sagasw

unread,
Dec 28, 2009, 8:28:19 AM12/28/09
to pon...@googlegroups.com
大家可否同时附上n = 5000(这个应该需要打印一段时间)时候的整个程序完成需要时间(包括屏幕输出时间,因为有些朋友的时间是一段段输出的)?

想看看不同语言、不同方法实现差别多大。

我的lua代码测试结果为
666.449秒,接近11分钟,
绝大部分用在输出结果上了。


Windows7,2G Core双核 2.5G内存
console方式运行lua xxx.lua

代码如下:

local currentCount = 1
local limitNum = 5000

local currentLevel = 0
local result = {}

function AddY(x, y)
    if currentCount > limitNum * limitNum then
        return
    else
        if y > (limitNum - currentLevel) then
            return AddX(x + 1, y - 1)
        end

        result[(x -1)* limitNum + y] = currentCount
        currentCount = currentCount + 1
        y = y + 1
        return AddY(x, y)
    end
end

function AddX(x, y)
    if currentCount > limitNum * limitNum then
        return
    else
        if x > (limitNum - currentLevel) then
            return MinusY(x - 1, y - 1)
        end

        result[(x -1)* limitNum + y] = currentCount
        currentCount = currentCount + 1
        x = x + 1
        return AddX(x, y)
    end
end

function MinusY(x, y)
    if currentCount > limitNum * limitNum then
        return
    else
        if y < (1 + currentLevel) then
            currentLevel = currentLevel + 1
            return MinusX(x -1, y + 1)
        end

        result[(x -1)* limitNum + y] = currentCount
        currentCount = currentCount + 1
        y = y - 1
        return MinusY(x, y)
    end
end

function MinusX(x, y)
    if currentCount > limitNum * limitNum then
        return
    else
        if x < (1 + currentLevel) then
            return AddY(x + 1, y + 1)
        end

        result[(x -1)* limitNum + y] = currentCount
        currentCount = currentCount + 1
        x = x - 1
        return MinusX(x, y)
    end
end

local time1 = os.clock()

AddY(1, 1)

print("--------------")

for i = 1, limitNum do
    local linestr = table.concat(result, "    ", (i -1) * limitNum + 1, (i -1) * limitNum + limitNum)
    print(linestr)
end

local time2 = os.clock()
print(time2 - time1)



------------------------------------
C++, Lua, living in Dalian
http://sunxiunan.com/
http://twitter.com/sagasw
------------------------------------


2009/12/28 Shuo Chen <gian...@gmail.com>

Wu Yin

unread,
Dec 28, 2009, 8:35:31 AM12/28/09
to pon...@googlegroups.com
你那叫输出到屏幕上了。
你往文件里写个看看,保证速度有质的飞跃

2009/12/28 sagasw <sag...@gmail.com>



--
滚滚长江东逝水,浪花淘尽英雄。
是非成败转头空。
青山依旧在,几度夕阳红。
白发渔樵江渚上,惯看秋月春风。
一壶浊酒喜相逢。
古今多少事,都付笑谈中。

Shuo Chen

unread,
Dec 28, 2009, 8:40:48 AM12/28/09
to TopLanguage
这个,每个人机器不一样,没有可比性嘛。要不都在你的机器上试试?

On Dec 28, 9:28 pm, sagasw <sag...@gmail.com> wrote:
> 大家可否同时附上*n = 5000*(这个应该需要打印一段时间)时候的整个程序完成需要时间(包括屏幕输出时间,因为有些朋友的时间是一段段输出的)?
>
> 想看看不同语言、不同方法实现差别多大。
>
> 我的lua代码测试结果为
> *666.449秒*,接近11分钟,

wang tiger

unread,
Dec 28, 2009, 8:49:40 AM12/28/09
to pon...@googlegroups.com
     采用分段的方式赋值

#include<iostream>
using namespace std;

int main()
{
 int k=0;
 
 cout<<"input number"<<endl;
 int **a;
 int i,j;
 cin>>k;

 a=new int *[k];
 for(i=0;i<k;i++)
 {
  a[i]=new int[k];
 }

 for(i=0;i<k;i++)
  for(j=0;j<k;j++)
  {
   a[i][j]=0;
  }

        /*赋值回形数*/
  int col=0,row=0;
  int num=1;
  int count;
  int tempRow;

     /*
   按照顺时针的方式赋值数组
  */
  for(i=k;i>=0;i=i-2)
  {
   
            tempRow=row;
   count=0;
   col=row;

   //i代表每行要赋值的个数

   while(count<i)
   {
    a[row][col]=num;
    count++;
    num++;
    col++;
   }

   col--;

   for(row++;row<=col;row++)
   {
    a[row][col]=num;
    num++;
   }

   row--;

   for(col--;col>=tempRow;col--)
   {
    a[row][col]=num;
    num++;
   }

   col++;

   for(row--;row>tempRow;row--)
   {
    a[row][col]=num;
    num++;
   }

   row=tempRow;
   row++;
  }
  

 //输出二维数组
 for(i=0;i<k;i++)
 {
  for(j=0;j<k;j++)
  {
   cout<<" , "<<a[i][j];  
  }
  cout<<endl;
 }
 return 0;
}


张沈鹏

unread,
Dec 28, 2009, 9:31:54 AM12/28/09
to pon...@googlegroups.com
def print_n(n):
    r = [n*[None] for i in range(n)]
    xy = [0, 0]
    d = 1
    s = 1
    for i in range(1, 1+n*n):
        r[xy[0]][xy[1]] = i
        m = xy[:]
        m[d] += s
        if m[d] >= n or r[m[0]][m[1]] is not None:
            if d == 1:
                d = 0
            else:
                s = -s
                d = 1
        xy[d] += s
    print "\n".join(" ".join(map(lambda x:"%4s"%x, i)) for i in r)


print_n(5)
print_n(25)

DJ_scut

unread,
Dec 28, 2009, 9:39:24 AM12/28/09
to TopLanguage
#include<iostream>
using namespace std;

typedef int (*f)(const int,int &,int&);

int right(const int a,int&x,int&y)
{return ++x+y*a;}

int down(const int a,int&x,int&y)
{return x+(++y)*a;}

int left(const int a,int&x,int&y)
{return --x+y*a;}

int up(const int a,int&x,int&y)
{return x+(--y)*a;}

int main()
{
int a=0;
cin>>a;
int *ary=new int[a*a];
int n=1,x=-1,y=0;
f pfs[4]={right,down,left,up};
f pf=0;
for(int idx=0;idx<2*a-1;++idx)
{
pf=pfs[idx%4];
for(int idx2=0;idx2<(a-(idx+1)/2);idx2++)
ary[pf(a,x,y)]=n++;
}

for(int i=0;i<a;++i)
{
for(int j=0;j<a;++j)
cout<<ary[i*a+j]<<'\t';
cout<<endl;
}
}

呵呵,花了半个多小时写的..因为没怎么用过函数指针就蛋疼用用...


On Dec 28, 11:30 am, Shuo Chen <giantc...@gmail.com> wrote:

sagasw

unread,
Dec 28, 2009, 9:45:05 AM12/28/09
to pon...@googlegroups.com
写文件比写屏快,这个
真的
不需要指点,
我想知道的就是计算加上输出的时间,
现在机器的差别应该也不至于差很多,除非你是108核的机器。

另外,不知道你有没有看我写的:
绝大部分用在输出结果上了。

因为楼主要求的是“画图”,光要求计算或者输出到文件,
能合乎题目么?给我解释80*25什么的不也是因为要屏显么?



------------------------------------
C++, Lua, living in Dalian
http://sunxiunan.com/
http://twitter.com/sagasw
------------------------------------


2009/12/28 Wu Yin <wyw...@gmail.com>

sagasw

unread,
Dec 28, 2009, 9:46:30 AM12/28/09
to pon...@googlegroups.com
把你的机器配置写出来就好了,
机器配置能影响多少呢?


------------------------------------
C++, Lua, living in Dalian
http://sunxiunan.com/
http://twitter.com/sagasw
------------------------------------


2009/12/28 Shuo Chen <gian...@gmail.com>

Shuo Chen

unread,
Dec 28, 2009, 9:57:48 AM12/28/09
to TopLanguage
原文要求i<=25 是为了方便输出到屏幕,现在既然 i == 5000,这样吧,都重定向到文件好了。

time ./a.out > /dev/null

On Dec 28, 10:45 pm, sagasw <sag...@gmail.com> wrote:
> 写文件比写屏快,这个
> *真的*


> 不需要指点,
> 我想知道的就是计算加上输出的时间,
> 现在机器的差别应该也不至于差很多,除非你是108核的机器。
>
> 另外,不知道你有没有看我写的:

> *绝大部分用在输出结果上了。*


>
> 因为楼主要求的是"画图",光要求计算或者输出到文件,
> 能合乎题目么?给我解释80*25什么的不也是因为要屏显么?
>
> ------------------------------------

> C++, Lua, living in Dalianhttp://sunxiunan.com/http://twitter.com/sagasw
> ------------------------------------
>

> 2009/12/28 Wu Yin <wyw...@gmail.com>
>
> > 你那叫输出到屏幕上了。
> > 你往文件里写个看看,保证速度有质的飞跃
>
> > 2009/12/28 sagasw <sag...@gmail.com>
>

> >> 大家可否同时附上*n = 5000*(这个应该需要打印一段时间)时候的整个程序完成需要时间(包括屏幕输出时间,因为有些朋友的时间是一段段输出的)?
>
> >> 想看看不同语言、不同方法实现差别多大。
>
> >> 我的lua代码测试结果为
> >> *666.449秒*,接近11分钟,

> >> 2009/12/28 Shuo Chen <giantc...@gmail.com>


>
> >>> 屏幕一行80列。
>
> >>> On Dec 28, 8:29 pm, sagasw <sag...@gmail.com> wrote:
> >>> > i < 25 这个限制有什么用?
>
> >>> > ------------------------------------

> >>> > C++, Lua, living in Dalianhttp://
> >>> sunxiunan.com/http://twitter.com/sagasw
> >>> > ------------------------------------
>

Shuo Chen

unread,
Dec 28, 2009, 10:06:00 AM12/28/09
to TopLanguage
X5150, Linux, g++ 3.4
32-bit, 4.3s
64-bit, 3.9s

On Dec 28, 10:46 pm, sagasw <sag...@gmail.com> wrote:
> 把你的机器配置写出来就好了,
> 机器配置能影响多少呢?
>
> ------------------------------------

> > > > > C++, Lua, living in Dalianhttp://
> > sunxiunan.com/http://twitter.com/sagasw
> > > > > ------------------------------------
>

Fei Yan

unread,
Dec 28, 2009, 10:08:31 AM12/28/09
to pon...@googlegroups.com
 我也来一个python版的,不过是练手目的:

#!/usr/bin/env python
def getNext(dim):
    row = 0
    col = -1

    grpCnts = dim + 1
    curNum = 0
    directionMagic = 3
    # 0 -> col++; 1 -> row++; 2-> col--; 3-> row--
    consumed = grpCnts
   
    while True:
        if grpCnts == 0:
            return
        # Check and change directions
        if consumed == grpCnts:
            consumed = 0 #clear
            if directionMagic == 1 or directionMagic == 3 :
                grpCnts -= 1
            directionMagic = (directionMagic + 1) % 4
            #print "before corner point, current num %d grpCnts %d directionMagic %d"%(curNum, grpCnts, directionMagic)

        if grpCnts == 0:
            return

        #Yield the next point
        consumed += 1
        curNum += 1
        added = directionMagic < 2 and 1 or -1
        if directionMagic % 2 == 0:
            col += added
        else:
            row += added
        yield (row, col, curNum)

def prettyPrint(dim):
    result = {}
    for tpl in getNext(dim):
        row, col, num = tpl
        #print "yielding <%d> at <%d, %d>"%(num, row, col)
        if not result.has_key(row):
            result[row] = {}
        result[row][col] = num
    maxwidth = len(str(dim*dim)) + 1
    for row,nums in result.items():
        for num in nums.itervalues():
            print ('%' + str(maxwidth) + 'd')%num,
        print '\n'

if __name__ == '__main__':
    import sys
    prettyPrint(int(sys.argv[1]))


粗略测试了一下,跑2000个需要14.6s, 1000个需要4.6s, 5000个。。。memory不断在reasync(512M的VirtuanBox Ubuntu client,不很强劲)
我这个性能在内存而不在文件IO;此外python也不是我的主开发语言。

2009/12/28 Shuo Chen <gian...@gmail.com>

Shuo Chen

unread,
Dec 28, 2009, 10:08:53 AM12/28/09
to TopLanguage
直接用 lua 打印从 1 到 25000000 的整数用时多少?刨开这个时间,比较才有意义,对吧。不然就成了比各种语言的 IO 效率了。

On Dec 28, 9:28 pm, sagasw <sag...@gmail.com> wrote:

> 大家可否同时附上*n = 5000*(这个应该需要打印一段时间)时候的整个程序完成需要时间(包括屏幕输出时间,因为有些朋友的时间是一段段输出的)?
>
> 想看看不同语言、不同方法实现差别多大。
>
> 我的lua代码测试结果为
> *666.449秒*,接近11分钟,

sagasw

unread,
Dec 28, 2009, 10:18:04 AM12/28/09
to pon...@googlegroups.com
我在你另外的帖子里回复过题意不清的意见,
不知道你有没有看过前面朋友的回答,有的人是把结果存入某个表、数组,
有的就直接打印出来了,
我是第一次知道画图是把结果写到文件里,这点算是我有些抬杠。
既然你说抛开IO,那为何还要写文件,难道写文件不是IO,抱歉,这点又是抬杠。

干脆不如这样,直接算完就拉倒,也不写文件,也不屏显,最能体现不同计算方式的性能。

当然,这些都是无所谓、瞎扯罢了。


------------------------------------
C++, Lua, living in Dalian
http://sunxiunan.com/
http://twitter.com/sagasw
------------------------------------


2009/12/28 Shuo Chen <gian...@gmail.com>

cutepig

unread,
Dec 28, 2009, 10:28:54 AM12/28/09
to TopLanguage
上一个很弱的代码
#include <vector>
#include <cassert>

struct Matrix
{
std::vector<int> vData;
int size_;

explicit Matrix(int size)
: vData(size*size), size_(size)
{}

int& operator()(int y, int x)
{
return vData[y*size_+x];
}
};

void main()
{
int n = 0;
printf("Input n:");
scanf("%d", &n);

Matrix mat(n);
int y=0,x=0;
int inc[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
int id=0;
for(int i=0; i<n*n; i++)
{
assert(!(x<0 || x>=n || y<0 || y>=n || mat(y,x)));
mat(y,x) = i+1;
//printf("y %d x %d data %d\n", y, x, i+1);
int dx=inc[id%4][0];
int dy=inc[id%4][1];
if(x+dx<0 || x+dx>=n || y+dy<0 || y+dy>=n || mat(y+dy,x+dx))
{
id++;
dx=inc[id%4][0];
dy=inc[id%4][1];
}
x+=dx;
y+=dy;
}

for(y=0; y<n; y++)
{
for(int x=0; x<n;x++)
{
printf("%4d", mat(y,x));
}
printf("\n");
}
}

Shuo Chen

unread,
Dec 28, 2009, 10:40:24 AM12/28/09
to TopLanguage
前面有人直接用公式算的,没用表也没用数组,不写文件就等于没有计算嘛。
如果是输出到Windows Console,你拿个窗口把它遮住,速度会快很多,不信你试试。
就算写文件也做不到完全公平,因为i==5000的输出有200M,笔记本的硬盘大概要5、6秒才能写完,而台式机只要3、4秒。
如果服务器磁盘缓存够大,一秒也不到。所以我提议重定向到 /dev/null,这样免得比较各人的磁盘性能。
性能测试是个很微妙的事儿,标准不同,结果差出去几条街。

On Dec 28, 11:18 pm, sagasw <sag...@gmail.com> wrote:
> 我在你另外的帖子里回复过题意不清的意见,
> 不知道你有没有看过前面朋友的回答,有的人是把结果存入某个表、数组,
> 有的就直接打印出来了,
> 我是第一次知道画图是把结果写到文件里,这点算是我有些抬杠。
> 既然你说抛开IO,那为何还要写文件,难道写文件不是IO,抱歉,这点又是抬杠。
>
> 干脆不如这样,直接算完就拉倒,也不写文件,也不屏显,最能体现不同计算方式的性能。
>
> 当然,这些都是无所谓、瞎扯罢了。
>
> ------------------------------------

> > > > > C++, Lua, living in Dalianhttp://
> > sunxiunan.com/http://twitter.com/sagasw
> > > > > ------------------------------------
>

Yishi Guo

unread,
Dec 28, 2009, 6:48:17 PM12/28/09
to pon...@googlegroups.com
附上C++的小程序,如果只计算的话是495ms。如果加上输出的话,应该要半个多小时。

#include <iostream>
#include <time.h>
#define MAX 5000
using namespace std;


int array[MAX][MAX] = { {0} };

void output_array( int array[MAX][MAX], int n ) {
for ( int i = 0; i < n; ++i ) {
for ( int j = 0; j < n; ++j ) {
cout << array[i][j] << "\t";
}
cout << endl;
}
cout << endl;
}

void play_game() {
long i;
cout << "Input the number: ";
cin >> i;

int clock1 = clock();

int row = 0, col = 0;
int k = i;
int j = k;
int flag = 0;
for ( long index = 0; index < i * i; index++ ) {

if ( --j <= 0 ) {
if ( flag % 2 == 0 ) {
j = --k;
} else {
j = k;
}
flag++;
}

array[row][col] = index+1;

switch( flag % 4 ) {
case 0:
col++;
break;
case 1:
row++;
break;
case 2:
col--;
break;
case 3:
row--;
break;
}
}
int clock2 = clock();

cout << "Time: " << clock2 - clock1 << endl;

output_array( array, i );

int clock3 = clock();

cout << "Time: " << clock3 - clock1 << endl;
}

int main() {

while( 1 ) {
play_game();
}

return 0;
}
--
iStone
http://meiyou.org

Shuo Chen

unread,
Dec 28, 2009, 6:57:33 PM12/28/09
to TopLanguage
惊现谭浩强版 i/j/k/flag/index 。

Shuo Chen

unread,
Dec 28, 2009, 7:31:07 PM12/28/09
to TopLanguage
把 cout << endl 改为 cout << '\n' ,然后重定向到 /dev/null,我的测试结果是 4.04s。

On Dec 29, 7:48 am, Yishi Guo <baicaib...@gmail.com> wrote:

Fei Yan

unread,
Dec 28, 2009, 8:23:40 PM12/28/09
to pon...@googlegroups.com
机器的差别还真大;我的程序尚未做任何优化,貌似是否重定向影响不大(稍后可以用cStringIO试试,否则print铁定吃亏)。
换了台IBM的x86:

 time ./circle_matrix.py 1000 > /dev/null

real    0m3.289s
user    0m3.263s
sys     0m0.027s

 time ./circle_matrix.py 5000 > /dev/null

real    1m24.302s
user    1m23.604s
sys     0m0.650s

Fedora 12-Linux, 2GB RAM, Intel Xeon CPU  E3110 @ 3.00 GHZ, 6144KB Cache

2009/12/28 Fei Yan <skyscr...@gmail.com>

Fei Yan

unread,
Dec 28, 2009, 8:35:14 PM12/28/09
to pon...@googlegroups.com
用我的IBM测,即使不修改'\n',重定向版本计算只有250K ticks (/1000000 = 0.25s),输出为4.57M ticks = 4.57s.

2009/12/29 Shuo Chen <gian...@gmail.com>

Shuo Chen

unread,
Dec 28, 2009, 10:23:15 PM12/28/09
to TopLanguage
小测试:
我把 fill() 从四个循环改为一个循环:

int fill(int start, int left, int up, int right, int down)
{
int n = right-left;
for (int i = 0; i < n; ++i) {
maze[left+i][up] = start+i;
maze[right][up+i] = start+i+n;
maze[right-i][down] = start+i+2*n;
maze[left][down-i] = start+i+3*n;
}
return start + 4*n;
}

程序的结果不变,但是速度略有变化,问:你认为可能变快还是变慢?为什么?

On Dec 28, 4:35 pm, Shuo Chen <giantc...@gmail.com> wrote:
> 把我自己的贴一下,C 写的,非递归版。
>
> #include <stdio.h>
> #include <stdlib.h>
>
> int maze[25][25];
>
> int fill(int start, int left, int up, int right, int down)
> {
> int now = start;
> for (int i = left; i < right; ++i)
> maze[i][up] = now++;
> for (int i = up; i < down; ++i)
> maze[right][i] = now++;
> for (int i = right; i > left; --i)
> maze[i][down] = now++;
> for (int i = down; i > up; --i)
> maze[left][i] = now++;
> return now;


>
> }
>
> int main(int argc, char* argv[])
> {

> int N = atoi(argv[1]);
> int start = 1;
> int left = 0, right = N-1, up = 0, down = N-1;
>
> for (int i = 0; i < N/2; ++i) {
> start = fill(start, left, up, right, down);
> ++left, --right, ++up, --down;
> }
>
> if (N % 2 == 1)
> maze[left][up] = start;
>
> for (int i = 0; i < N; ++i) {
> for (int j = 0; j < N; ++j) {
> printf("%*d ", N < 10 ? 2 : 3, maze[j][i]);
> }
> printf("\n");
> }
>
> }
>
> 欢迎批评。


>
> On Dec 28, 11:30 am, Shuo Chen <giantc...@gmail.com> wrote:
>

Shuo Chen

unread,
Dec 28, 2009, 10:34:21 PM12/28/09
to TopLanguage
再改了一次,这次速度有相反的变化,问为什么?

int fill(int start, int left, int up, int right, int down)
{
int n = right-left;
for (int i = 0; i < n; ++i) {

maze[left][up+i+1] = start-i-1+4*n;


maze[right][up+i] = start+i+n;
maze[left+i][up] = start+i;

maze[left+i+1][down] = start-i-1+3*n;
}
return start + 4*n;
}

前一次变了10%,这次变了4%。一次变快一次变慢,问你觉得哪次快哪次慢?

王二

unread,
Dec 28, 2009, 11:26:54 PM12/28/09
to pon...@googlegroups.com
贴一个C的:
#include <stdio.h>
#define N 5

int main()
{
int type, i, j, n, t[N+2][N+2];
type=3;
n=1;

for(i=0;i<N+2;i++)
for(j=0;j<N+2;j++)
t[i][j]=0;

for(j = 0; j < N+2; j++)
t[0][j] = t[N+1][j] = 1;

for(i = 1; i < N+2; i++)
t[i][0] = t[i][N+1] =1;

i=j=0;

while(n < N*N)
{
while(type == 3)
{
t[i+1][j+1] = n;
if(t[i+1][j+2])
{
type = 1;
break;
}
j++;
n++;
}
while(type == 1)
{
t[i+1][j+1]=n;
if(t[i+2][j+1])
{
type = 2;
break;
}
i++;
n++;
}
while(type == 2)
{
t[i+1][j+1]=n;
if(t[i+1][j])
{
type = 0;
break;
}
j--;
n++;
}
while(type == 0)
{
t[i+1][j+1]=n;
if(t[i][j+1])
{
type = 3;
break;
}
i--;
n++;
}
}

for(i=1;i<N+1;i++)
{
for(j=1;j<N+1;j++)
                     printf("%4d",t[i][j]);
printf("\n");
}
return 0;
}


2009/12/29 Shuo Chen <gian...@gmail.com>



--
王大鹏
HUST,Wuhan,China
博客:wong2.cn
Twitter:twitter.com/wonderfuly

Clumsy

unread,
Dec 28, 2009, 11:57:59 PM12/28/09
to TopLanguage
灵感来自一个打印菱形的程序。

#include <iostream>
using namespace std;

int main()
{
int a[26][26],n,i,j,c,p,q;
while(1)
{
cin>>n;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
a[i][j]=0;
for(c=2,i=j=0,p=0,q=1,a[i][j]=1;c<=n*n;c++)
{
i+=p;
j+=q;
a[i][j]=c;
if((a[i+p][j]&&a[i][j]!=(a[i+p][j]-1)&&a[i][j]!=a[i+p][j])||i+p==n||
i+p<0)
{
if(p==1)
{
p=0;
q=-1;
}
else
{
p=0;
q=1;
}
}
else if((a[i][j+q]&&a[i][j]!=(a[i][j+q]-1)&&a[i][j]!=a[i][j+q])||j
+q==n||j+q<0)
{
if(q==1)
{
p=1;
q=0;
}
else
{
p=-1;
q=0;
}
}
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
printf("%3d ",a[i][j]);

Simon Liu

unread,
Dec 29, 2009, 5:48:58 AM12/29/09
to pon...@googlegroups.com
发一个比较短的Python版本
 
MAX = 10
matrix = [[0 for col in range(MAX)] for row in range(MAX)]
(x, y, count, link) = (-1, 0, 1, {1:(1,0,2), 2:(0,1,3), 3:(-1,0,4), 4:(0,-1,1)})
(dx, dy, direct) = link[1]
while count <= MAX*MAX:
    (nx, ny) = (x + dx, y + dy)
    if (0 <= nx < MAX) and (0 <= ny < MAX) and (matrix[ny][nx] == 0):
        matrix[ny][nx] = count
        (x, y, count) = (nx, ny, count + 1)
    else:
        (dx, dy, direct) = link[direct]
       
for x in range(MAX):
    print matrix[x]

Simon Liu

unread,
Dec 29, 2009, 5:52:10 AM12/29/09
to pon...@googlegroups.com
PS, 还能更短否?

2009/12/29 Simon Liu <yunta...@gmail.com>



--
刘金雨(云涛)
Email/MSN/GTalk: yuntao.liu(AT)gmail.com

pp

unread,
Dec 29, 2009, 3:36:06 AM12/29/09
to TopLanguage
除了第一行。往后每两行就长度减一(++offset)。从row转到col的时候方向改变。当offset == size结束
fillCol()和fillRow()互相call
加了个log10()来确定输出的格式于是任意大小都可以。MSDOS下size最大到25否则输出会乱
大三学生。听说大一学生分分钟就能写出来好紧张:)

import java.util.*;

public class HelixMatrix
{
private static int size;

public static void fillCol(int row, int col, int fill, boolean
direction, int offset, int[][] matrix)
{
if (offset <= size)
{
int step = (direction ? 1 : -1);
// System.out.println("fillCol() called\nStart with row "+row
+" col "+col+" step "+step);
for(int i = 0;i < size-offset;i++)
{
matrix[row][col] = fill++;
row += step;
}
fillRow(row-step, col-step, fill, !direction, offset,
matrix);
}
}

public static void fillRow(int row, int col, int fill, boolean
direction, int offset, int[][] matrix)
{
if (offset <= size)
{
int step = (direction ? 1 : -1);
// System.out.println("fillRow() called\nStart with row "+row
+" col "+col+" step "+step);
for(int i = 0;i < size-offset;i++)
{
matrix[row][col] = fill++;
col += step;
}
fillCol(row+step, col-step, fill, direction, offset+1,
matrix);
}
}

public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
size = sc.nextInt();
int[][] matrix = new int[size][size];
int fill = 1;
for(int i = 0;i < size;i++)
matrix[0][i] = fill++;
fillCol(1, size-1, fill, true, 1, matrix);

printMatrix(matrix);
}

public static void printMatrix(int[][] matrix)
{
String format = new String();
int length = 3 + (int) Math.floor(Math.log10(size));
format = "%"+length+"d";
for(int i = 0;i < size;i++)
{
for(int j = 0;j < size;j++)
{
System.out.print(new String().format(format, matrix[i]
[j]));
}
System.out.print("\n");
}
}
}

hill wang

unread,
Dec 29, 2009, 6:25:01 AM12/29/09
to pon...@googlegroups.com
void roll(int num, int times)
{
    int i = 0,j = 0;
    if(1 == num)
    {
        a[times + i][times + j] = value++;
        return;
    }
    for(j = 0; j < num; j++)
        a[times + i][times + j] = value++;
    j++;
    for(i = 0; i < num; i++)
        a[times + i][times + j] = value++;
    i++;
    for(;j > 0; j--)
        a[times + i][times + j] = value++;
    j--;
    for(;i > 0; i--)
        a[times + i][times + j] = value++;
    i--;
}

main()
{
    scanf("%d",&i);
    int times = 0;
    int num = i;
    while(num > 0)
    {
        roll(num, times);
        times++;
    }
}

2009/12/28 Shuo Chen <gian...@gmail.com>

jun lin

unread,
Dec 29, 2009, 6:44:46 AM12/29/09
to pon...@googlegroups.com
感觉像是我写的精简版本。。
+1

2009/12/29 Simon Liu <yunta...@gmail.com>

Simon Liu

unread,
Dec 29, 2009, 6:46:45 AM12/29/09
to pon...@googlegroups.com
是啊 都是Python的

2009/12/29 jun lin <linjun...@gmail.com>



--
刘金雨(云涛)
Email/MSN/GTalk: yuntao.liu(AT)gmail.com

jun lin

unread,
Dec 29, 2009, 6:51:29 AM12/29/09
to pon...@googlegroups.com
主要是逻辑上差不多。。。
这道题的解法好像有2个,按照题目的方法来转圈,
或者直接算结果?

2009/12/29 Simon Liu <yunta...@gmail.com>

jun lin

unread,
Dec 29, 2009, 6:53:13 AM12/29/09
to pon...@googlegroups.com
转圈要消耗n**2的空间和时间,
直接算的话,消耗常数的空间和n**2的时间。。。。

2009/12/29 jun lin <linjun...@gmail.com>

Mikster.Z

unread,
Dec 29, 2009, 7:19:51 AM12/29/09
to pon...@googlegroups.com
未必吧~~拟合出一条定义在X,Y上的螺旋曲线就可以O(n),但是我不会弄~~~也不知道能不能弄~~ :)

2009/12/29 jun lin <linjun...@gmail.com>



--
EX - EMBEDDED SYSTEM DEVELOPER
SOFTWARE ENGINEER
Name : Mikster  

Shuo Chen

unread,
Dec 29, 2009, 8:29:38 AM12/29/09
to TopLanguage
取决于你们俩怎么定义 n,
n 是边长,那么复杂度是 O(n**2),
n 是矩阵的元素个数,那么复杂度是 O(n)。
如果 n 是边长,由于输出有 n*n 个元素,复杂度不可能小于 O(n**2),当然也不可能大于。

On Dec 29, 8:19 pm, "Mikster.Z" <chinamix...@gmail.com> wrote:
> 未必吧~~拟合出一条定义在X,Y上的螺旋曲线就可以O(n),但是我不会弄~~~也不知道能不能弄~~ :)
>

> 2009/12/29 jun lin <linjunhal...@gmail.com>
>
>
>
> > 转圈要消耗n**2的空间和时间,
> > 直接算的话,消耗常数的空间和n**2的时间。。。。
>
> > 2009/12/29 jun lin <linjunhal...@gmail.com>
>
> >> 主要是逻辑上差不多。。。
> >> 这道题的解法好像有2个,按照题目的方法来转圈,
> >> 或者直接算结果?
>
> >> 2009/12/29 Simon Liu <yuntao....@gmail.com>
>
> >>> 是啊 都是Python的
>
> >>> 2009/12/29 jun lin <linjunhal...@gmail.com>
>
> >>> 感觉像是我写的精简版本。。
> >>>> +1
>
> >>>> 2009/12/29 Simon Liu <yuntao....@gmail.com>

line head

unread,
Dec 30, 2009, 4:21:37 AM12/30/09
to pon...@googlegroups.com
ms好久前在一个叫啥程序员面试宝典里看到过这个 环形数组,我想知道通项公式如何求出,而不是用模拟的方法。通项的话,参数是整数数值和行或列的数量,输出为i,j。

2009/12/29 Shuo Chen <gian...@gmail.com>

Jacky, Z

unread,
Dec 30, 2009, 5:10:53 AM12/30/09
to pon...@googlegroups.com
想求通项就一定可以做到,或者看我上边写的。
2009/12/30 line head <luckhe...@gmail.com>

Simon Liu

unread,
Dec 30, 2009, 6:04:17 AM12/30/09
to pon...@googlegroups.com
原帖里面看到这么段代码,很赞
验证之后果然可用,不过7-11行没看懂。。。哪位明白能给解释一下是个什么逻辑

  1. #include <stdio.h>   
  2. #define N 10  
  3. int main(){  
  4.     int a[N*N],x=0,y=0,m=0,i;  
  5.     for(i=0;i<N*N;i++){  
  6.         a[x+y*N]=i;  
  7.         x+=((m+1)&1)*(1-m);  
  8.         y+=((m+0)&1)*(2-m);  
  9.         if(x==y||x+y==N-1){  
  10.             m=++m&3;  
  11.             if(!m)x=++y;  
  12.         }  
  13.     }  
  14.     for(i=0;i<N*N;i++)  
  15.         printf("%02d%c",a[i],(i%N+1)/N*10);  
  16. }   



2009/12/30 Jacky, Z <fans...@gmail.com>



--
刘金雨(云涛)
Email/MSN/GTalk: yuntao.liu(AT)gmail.com

Mikster.Z

unread,
Dec 30, 2009, 6:07:51 AM12/30/09
to pon...@googlegroups.com
directions~~if的是判断角落则转向~
某种条件下交换xy
2009/12/30 Simon Liu <yunta...@gmail.com>

Mikster.Z

unread,
Dec 30, 2009, 6:08:10 AM12/30/09
to pon...@googlegroups.com
还是转圈派~~

2009/12/30 Mikster.Z <china...@gmail.com>

Simon Liu

unread,
Dec 30, 2009, 6:12:36 AM12/30/09
to pon...@googlegroups.com
还是转圈?不是吧?这个逻辑很明显跟楼上的所有的都不一样。
至少分明是通过元素i下标在算xy,而不是反之,怎么可能是在转圈?

2009/12/30 Mikster.Z <china...@gmail.com>



--
刘金雨(云涛)
Email/MSN/GTalk: yuntao.liu(AT)gmail.com

Mikster.Z

unread,
Dec 30, 2009, 6:14:32 AM12/30/09
to pon...@googlegroups.com
。。。。。当然是在转圈了~~~你仔细点看就知道了~~~

2009/12/30 Simon Liu <yunta...@gmail.com>

Simon Liu

unread,
Dec 30, 2009, 6:17:37 AM12/30/09
to pon...@googlegroups.com
我看不懂,
  1.         x+=((m+1)&1)*(1-m);  
  2.         y+=((m+0)&1)*(2-m);  

这两行里面的xy为什么这样计算?

2009/12/30 Mikster.Z <china...@gmail.com>



--
刘金雨(云涛)
Email/MSN/GTalk: yuntao.liu(AT)gmail.com

Mikster.Z

unread,
Dec 30, 2009, 6:23:21 AM12/30/09
to pon...@googlegroups.com
方向啊~~~
M=0,1,2,3的时候x跟y的增量,你可以自己算

(x==y||x+y==N-1)这个是四个顶点

m=++m&3;  这个是转向~~~

你试试把每一步的m,x,y,i都输出来看看


2009/12/30 Simon Liu <yunta...@gmail.com>

Shuo Chen

unread,
Dec 30, 2009, 6:29:33 AM12/30/09
to TopLanguage
通项公式可以自己推嘛,就是简单的等差数列求和、分段函数和一元二次方程,高中数学知识就够了。

比如我这个:

struct Point
{
int x, y;
};

int getLayer(int N, int i)
{
return static_cast<int>(ceil((N - sqrt(N*N - i))/2));
}

int sumLayer(int N, int layer)
{
return layer*4*(N - layer);
}

Point calc(int N, int i)
{
int layer = getLayer(N, i);
int sum = sumLayer(N, layer-1);
int offset = i - sum - 1;
int row = N+1-2*layer;
Point p;
if (row == 0) {
p.x = layer - 1;
p.y = layer - 1;
} else {
int region = offset / row;
int delta = offset % row;

switch (region) {
case 0:
p.x = layer-1+delta;
p.y = layer-1;
break;
case 1:
p.x = N-layer;
p.y = layer-1+delta;
break;
case 2:
p.x = N-layer-delta;
p.y = N-layer;
break;
case 3:
p.x = layer-1;
p.y = N-layer-delta;
break;
default:
assert(0 && "Unknown region");
break;
}
}

return p;
}

int main(int argc, char* argv[])
{
int N = atoi(argv[1]);

for (int i = 1; i <= N*N; ++i) {
Point p = calc(N, i);
printf("%d %d %d\n", i, p.x, p.y);
}
}

On Dec 30, 5:21 pm, line head <luckheadl...@gmail.com> wrote:
> ms好久前在一个叫啥程序员面试宝典里看到过这个
> 环形数组,我想知道通项公式如何求出,而不是用模拟的方法。通项的话,参数是整数数值和行或列的数量,输出为i,j。
>

> 2009/12/29 Shuo Chen <giantc...@gmail.com>

n z

unread,
Dec 30, 2009, 12:45:26 PM12/30/09
to pon...@googlegroups.com
hui a 1 = [[a]]
hui a 2 = [[a, a+1],[a+3, a+2]]
hui a i = [[a..(a+i-1)]]++[[a+(i-1)*4-p]++as++[a+(i-1)+p]|(p,as)<-(zip [1..(i-2)] (hui (a + 4*(i-1)) (i-2)))]++[reverse[(a+(i-1)*2)..(a+(i-1)*3)]]


snake i = hui 1 i

Haskell 十分钟实现 其中八分钟查语法 不解释

Shuo Chen

unread,
Dec 30, 2009, 8:13:32 PM12/30/09
to TopLanguage
充分展现了 Haskell 作为可与 perl 媲美的 write-only 语言的潜质。

Mikster.Z

unread,
Dec 30, 2009, 8:26:28 PM12/30/09
to pon...@googlegroups.com
炫耀贴?对他人有帮助否?

形同:我家有1000亿,不解释。

2009/12/31 n z <jnn...@gmail.com>

jun lin

unread,
Dec 30, 2009, 9:19:15 PM12/30/09
to pon...@googlegroups.com
就是,强烈鄙视管杀不管埋。
代码可读性差,还不如把机器代码字节码之类的丢上来。。
好吧,不强求注释。。

2009/12/31 Mikster.Z <china...@gmail.com>

Jacky, Z

unread,
Dec 30, 2009, 11:01:08 PM12/30/09
to pon...@googlegroups.com
haskell曾经接触过,很久没用了
记得当初被其只有4行的快速排序震惊了

2009/12/31 n z <jnn...@gmail.com>

jun lin

unread,
Dec 30, 2009, 11:27:22 PM12/30/09
to pon...@googlegroups.com
行数少,复杂度还是一样的,只是从代码转移到语言实现上面。。
所以——make love no geeking..

2009/12/31 Jacky, Z <fans...@gmail.com>

Nan Hu

unread,
Dec 30, 2009, 11:38:44 PM12/30/09
to pon...@googlegroups.com
cmd.run("给我按楼主的要求打出来");

不解释.

纯粹搞笑,大家新年好.

2009/12/31 jun lin <linjun...@gmail.com>

YY H

unread,
Dec 30, 2009, 8:39:49 PM12/30/09
to pon...@googlegroups.com
如果不是用haskell的,只要看出是递归就可以了;如果是用hashkell的,就自己想想

2009/12/31 Mikster.Z <china...@gmail.com>:

kestrel

unread,
Dec 30, 2009, 11:09:56 PM12/30/09
to pon...@googlegroups.com

然后也要花上10分钟的时间来看懂?

Jeffrey Zhao

unread,
Dec 31, 2009, 3:04:35 AM12/31/09
to pon...@googlegroups.com
这明显是存心不让人看懂的写法,haskell又不是不能写成可读性强的。
 
 

Mikster.Z

unread,
Dec 31, 2009, 6:00:47 AM12/31/09
to pon...@googlegroups.com
问题是算法还不是新的。偏偏用了zhuangbility的发帖方式

2009/12/31 Jeffrey Zhao <je...@live.com>

n z

unread,
Jan 1, 2010, 4:52:37 AM1/1/10
to pon...@googlegroups.com
不解释是因为太晚了 旁边都在睡觉 打键盘会吵到人 
而且算法不是新的 我也觉得没必要解释 如果真的要解释的话 就只有解释HASKELL的语法了呃
而且都说十分钟写完 就是表示不考虑可读性的问题 其原因请参考第一条
如果LZ还不知道这道C++的第二次作业题怎么做的话 那.... 我.... 还是不解释


还有  新年快乐!

2009/12/31 Mikster.Z <china...@gmail.com>

Xpol Wan

unread,
Jan 3, 2010, 1:00:08 AM1/3/10
to pon...@googlegroups.com
我的代码和你写的基本一致。呵呵。
另外type的值可以考虑定义成宏提高可读性。

Best Regards!

Xpol Wan


2009/12/29 王二 <wonde...@gmail.com>
贴一个C的:
#include <stdio.h>
#define N 5

int main()
{
int type, i, j, n, t[N+2][N+2];
type=3;
n=1;

for(i=0;i<N+2;i++)
for(j=0;j<N+2;j++)
t[i][j]=0;

for(j = 0; j < N+2; j++)
t[0][j] = t[N+1][j] = 1;

for(i = 1; i < N+2; i++)
t[i][0] = t[i][N+1] =1;

i=j=0;

while(n < N*N)
{
while(type == 3)
{
t[i+1][j+1] = n;
if(t[i+1][j+2])
{
type = 1;
break;
}
j++;
n++;
}
while(type == 1)
{
t[i+1][j+1]=n;
if(t[i+2][j+1])
{
type = 2;
break;
}
i++;
n++;
}
while(type == 2)
{
t[i+1][j+1]=n;
if(t[i+1][j])
{
type = 0;
break;
}
j--;
n++;
}
while(type == 0)
{
t[i+1][j+1]=n;
if(t[i][j+1])
{
type = 3;
break;
}
i--;
n++;
}
}

for(i=1;i<N+1;i++)
{
for(j=1;j<N+1;j++)
                     printf("%4d",t[i][j]);
printf("\n");
}
return 0;
}


2009/12/29 Shuo Chen <gian...@gmail.com>
再改了一次,这次速度有相反的变化,问为什么?


int fill(int start, int left, int up, int right, int down)
{
 int n = right-left;
 for (int i = 0; i < n; ++i) {
   maze[left][up+i+1] = start-i-1+4*n;
   maze[right][up+i] = start+i+n;
   maze[left+i][up] = start+i;
   maze[left+i+1][down] = start-i-1+3*n;
 }
 return start + 4*n;
}

前一次变了10%,这次变了4%。一次变快一次变慢,问你觉得哪次快哪次慢?

On Dec 29, 11:23 am, Shuo Chen <giantc...@gmail.com> wrote:
> 小测试:
> 我把 fill() 从四个循环改为一个循环:
>
> int fill(int start, int left, int up, int right, int down)
> {
>   int n = right-left;
>   for (int i = 0; i < n; ++i) {
>     maze[left+i][up] = start+i;
>     maze[right][up+i] = start+i+n;
>     maze[right-i][down] = start+i+2*n;
>     maze[left][down-i] = start+i+3*n;
>   }
>   return start + 4*n;
>
> }
>
> 程序的结果不变,但是速度略有变化,问:你认为可能变快还是变慢?为什么?
>
> On Dec 28, 4:35 pm, Shuo Chen <giantc...@gmail.com> wrote:
>
> > 把我自己的贴一下,C 写的,非递归版。
>
> > #include <stdio.h>
> > #include <stdlib.h>
>
> > int maze[25][25];
>
> > int fill(int start, int left, int up, int right, int down)
> > {
> >   int now = start;
> >   for (int i = left; i < right; ++i)
> >     maze[i][up] = now++;
> >   for (int i = up; i < down; ++i)
> >     maze[right][i] = now++;
> >   for (int i = right; i > left; --i)
> >     maze[i][down] = now++;
> >   for (int i = down; i > up; --i)
> >     maze[left][i] = now++;
> >   return now;

>
> > }
>
> > int main(int argc, char* argv[])
> > {
> >   int N = atoi(argv[1]);
> >   int start = 1;
> >   int left = 0, right = N-1, up = 0, down = N-1;
>
> >   for (int i = 0; i < N/2; ++i) {
> >     start = fill(start, left, up, right, down);
> >     ++left, --right, ++up, --down;
> >   }
>
> >   if (N % 2 == 1)
> >     maze[left][up] = start;
>
> >   for (int i = 0; i < N; ++i) {
> >     for (int j = 0; j < N; ++j) {
> >       printf("%*d ", N < 10 ? 2 : 3, maze[j][i]);
> >     }
> >     printf("\n");
> >   }
>
> > }
>
> > 欢迎批评。
>
> > On Dec 28, 11:30 am, Shuo Chen <giantc...@gmail.com> wrote:
>
> > > 年底了,轻松一下。
>
> > >http://www.javaeye.com/topic/545378?page=1
>
> > > 一个画图程序 要求打印出
>
> > > int i=5;
> > >  1  2  3  4  5
> > > 16 17 18 19 6
> > > 15 24 25 20 7
> > > 14 23 22 21 8
> > > 13 12 11 10 9
>
> > > int i=6
> > >  1  2  3  4  5   6
> > > 20 21 22 23 24  7
> > > 19 32 33 34 25  8
> > > 18 31 36 35 26  9
> > > 17 30 29 28 27 10
> > > 16 15 14 13 12 11
>
> > > 我这里加一个限制,i<=25。
>
> > > 题目很简单,大一学生分分钟就能写出来。
> > > 语言不限,常规语言都行,C/C++/Java/C#/Ruby/Python/Perl。
> > > 代码简洁易懂为佳。(这里算是一个反例:http://www.javaeye.com/topic/557924
> > > 请各路高手各显神通,我会在第10楼贴出自己的C程序。



--
王大鹏
HUST,Wuhan,China
博客:wong2.cn
Twitter:twitter.com/wonderfuly

阮蒙铠

unread,
Jan 4, 2010, 4:06:31 AM1/4/10
to pon...@googlegroups.com
我写的一个C语言代码,循环做的,一直在关注这个讨论群,但自己也是刚起步,没能力发帖,还是回个贴吧。
#include <iostream>
#include <iomanip>
using namespace std;
#define MAX 20
void array_out(int n)
{
 int a[MAX][MAX];
 int row,col,num,k;
 row=col=0;
 num=1;
 k=n;
 while(n>0)
 {
  for(int i=0;i<n;i++,num++)
   a[row][col++] = num;
  n--;
  row++;
  col--;
  for(i=0;i<n;i++,num++)
   a[row++][col] = num;
  col--;
  row--;
  for(i=n;i>0;i--,num++)
   a[row][col--] = num;
  n--;
  row--;
  col++;
  for(i=n;i>0;i--,num++)
   a[row--][col] = num;
  col++;
  row++;
 }
 for(int i=0;i<k;i++)
 { 
  for(int j=0;j<k;j++)
   cout<<setw(4)<<a[i][j];
  cout<<endl;
 }
}
void main()
{
 array_out(20);
}


2010/1/3 Xpol Wan <xpo...@gmail.com>

Kenny Yuan

unread,
Jan 4, 2010, 4:32:34 AM1/4/10
to pon...@googlegroups.com
没想到这个贴能延续这么久,HO HO,刚才顺手也写了一个,虽然晚了点,也贴上来吧

原理类似洋葱,从外向内剥皮,每次生成一圈数据。


int& getElem(int x, int y);

void matrix(int size, int length, int vStart, int xyStart)
{
    if ( -- size == 0 )
        getElem(xyStart, xyStart) = vStart;

    for ( int i = 0 ; i < size ; ++ i )
    {
        getElem(xyStart+i, xyStart) = vStart + i; // Top
        getElem(xyStart + size, xyStart + i) = vStart + 1 * size + i; // Right
        getElem(xyStart + size - i, xyStart + size) = vStart + 2 * size + i; // Bottom
        getElem(xyStart, xyStart + size - i) = vStart + 3 * size + i; // Left
    }
}

void matrix(int N)
{
    int vStart = 1;
    int xyPos = 1;
    for ( int size = N ; size > 0 ; size -= 2, xyPos += 1 )
    {
        const int beltLength = size * 4 - 4;
        matrix(size, beltLength, vStart, xyPos);
        vStart += beltLength;
    }
}

asung0108

unread,
Jan 5, 2010, 4:10:59 AM1/5/10
to TopLanguage
和你的基本一样,至最后一个贴的吗?

#include <stdio.h>
#define N 5
#define MAX_BOXES ((N%2==0)?(N/2):(N/2+1))

int g_array[N][N];

/* start is the value in (i,j)
* size is the length of this box*/
void setBox(int start, int size, int i, int j)
{
int index=1;
int value = start;
/*set the top*/
for(;index<size;index++)
{
g_array[i][j++] = value++;
}
/*set the right*/
for(index=1;index<size;index++)
{
g_array[i++][j] = value++;
}
/*set the bottom*/
for(index=1;index<size;index++)
{
g_array[i][j--] = value++;
}
/*set the left*/
for(index=1;index<size;index++)
{
g_array[i--][j] = value++;
}
return;
}

int main(int argc, char **argv)
{
int i,j;
int box=0;
int start = 0;

g_array[0][0]=1;
i=0;j=0;
start = g_array[0][0];
do
{
setBox(start, N-box*2, i, j);
box++;
i = box; j = box;
start = g_array[i][j-1]+1;
}while(box<MAX_BOXES);

for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
{
printf("%4d", g_array[i][j]);
}
printf("\n");
}

getchar();
return 0;
}


On Jan 4, 5:32 pm, Kenny Yuan <yuankain...@gmail.com> wrote:

Reply all
Reply to author
Forward
0 new messages