左右间

行走在左右之间

博客园 首页 新随笔 联系 订阅 管理
  45 Posts :: 1 Stories :: 33 Comments :: 2 Trackbacks

2009年1月16日 #

幻方阵是一个矩阵,即将n*n(n>=3)个数字放入n*n的方格内,使方格的各行、各列及对角线上各数字之各相等。

Merzirac 算法。
在第最上面一行居中的方格内放1,依次向右上方填入2、3、4…,如果右上方已有数字,则向下移一格继续填写。如果坐标值超出上限,则归0,如果坐标值超出下限,则变为最大坐标值。

实现:
public static int[,] Generat(int n)
        {
            int[,] matrix = new int[n, n];

            int x = n / 2;
            int y = n-1;
            int maxNumber = n*n;
            for (int i = 1; i <= maxNumber; i++)
            {
                //修正坐标
                x = GetRealPositon(x, n);
                y = GetRealPositon(y, n);

                if (matrix[x, y] != 0)
                {
                    //到原始方格的正下方方格
                    x--;
                    y = y-2;
                    //修正坐标
                    x = GetRealPositon(x, n);
                    y = GetRealPositon(y, n);

                    //寻找原始方格的正下方中未被附值的方格
                    while (matrix[x, y] != 0)
                    {
                        y--;
                        y = GetRealPositon(y, n);
                    }
                }

                matrix[x, y] = i;

                //到右上角
                x++;
                y++;
            }

            return matrix;
        }

        private static int GetRealPositon(int x, int n)
        {
            if (x < 0)
                return n - 1;
            else if (x >= n)
                return 0;
            else
                return x;
        }

直接的数学公式。

N(I,J)=((I+J+(n-3)/2) MOD n)*n+(I-J+(3*n-1)/2) MOD n +1;

 

 

posted @ 2009-01-16 16:51 左右间 阅读(99) 评论(0) 编辑

2009年1月15日 #

问题分析:

假定N = 1, 则可能的整数集这能为{1}, 所以个数为1。

假定M = 1,N > 1, 则不可能有合适的整数集,所以个数为0。

假定M > N, 则结果集的个数和M = N的一样多, 因为不可能出现比N大的数。

假定M <= N, M > 1, N > 1, 此时我们有两种情况,结果集中包括M, 或者不包括。最终的数量为这两种情况的数量之和。


假定我们用F(N,M)来表示结果集的数量。则有如下表达式:

F(1,M) = 1; M为任意值.
F(N,1) = 0; N > 1.
F(N,M) = F(N,N); M > N.
F(N,M) = F(N - M,M - 1) + F(N,M - 1);M <= N, M > 1, N > 1.

一般有两种方式来解决这种问题,递归和动态规划。

递归方式:

        public static int GetPartitionCount2(int number, int maxElement)
        {
            if (number == 1)
                return 1;
            if (maxElement == 1)
                return 0;

            if (maxElement < number)
                return GetPartitionCount2(number - maxElement, maxElement - 1) + GetPartitionCount2(number, maxElement - 1);
            else
                return 1 + GetPartitionCount2(number, number - 1);
        }


动态规划:
public static int GetPartitionCount1(int number, int maxElement)
        {
            int[,] calculateTable = new int[number + 1, maxElement + 1];

            calculateTable[1, 1] = 1;

            for (int i = 2; i < number + 1; i++)
            {
                calculateTable[i, 1] = 0;
            }

            for (int i = 1; i < maxElement + 1; i++)
            {
                calculateTable[1, i] = 1;
            }

            for (int i = 2; i < maxElement + 1; i++)
            {
                for (int j = 2; j < number + 1; j++)
                {
                    if(i<j)
                        calculateTable[j, i] = calculateTable[j - i, i - 1] + calculateTable[j, i - 1];
                    else if(i>=j)
                        calculateTable[j, i] = 1 + calculateTable[j, j - 1];
                }
            }

            return calculateTable[number, maxElement];
        }

就递归方式而言,最大的不好之处就是递归次数太多,做了太多的冗余计算。

(N,M)          所需时间(ms)    
100,100        250
120,120         1281.3
140,140         6297
160,160         27484.7
180,180         110844.5
200,200         398417.4

相对而言,动态规划效率要高很多,不是一个数量级的。

(N,M)          所需时间(ms)    
1000,1000    46
2000,2000       187.5
3000,3000       593.8
4000,4000       1719.0
5000,5000       3172.3
6000,6000       5657.0
7000,7000    9345.1
8000,8000    13220.6
9000,9000    17736.9
10000,10000    22329.8

但是,在上面的动态规划算法中,有一个致命的地方就是数组分配,
int[,] calculateTable, 如果m,n较大,马上就内存溢出。
posted @ 2009-01-15 17:41 左右间 阅读(212) 评论(0) 编辑

2008年9月19日 #

1)用缩写。比如c:\Program Files缩写为c:\Progra~1
       再来刨根问底查查这个命名是否有规则,于是找到:
                 采用8个字符缩写,即写头六个字母(略去空白),另加波浪号和1,首字母不足六个字母,略去空白,用了第二个词的字母,凑成六个。例如:
                    "Documents and Settings“ -- DOCUME~1
                    "Local Settings" -- LOCALS~1 (注意略去空白,用了第二个词的字母,凑成六个,再加波浪号和1)。

  如果多个文件前6字符一样怎么办?为什么最后是1而不是0或者其他数字呢?看看这个例子
                假设下面是你的C盘根目录中的文件夹:
                    Program Files
                    Progra file
                    Progra zhang
                则三个目录分别表示为:C:\Progra~1; C:\Progra~2; C:\Progra~3;

2)绕过去,创建一个镜像。例如在cmd中输入 subst w: "C:\Documents and Settings\hopeshared"。然后就可以直接用w:\替代C:\Documents and Settings\hopeshared了

posted @ 2008-09-19 14:22 左右间 阅读(1637) 评论(1) 编辑

2008年8月31日 #

项目管理的一些常识:

  1. 不能一个项目组里全是专家,因为,第一,如果你的组员全部是专家的话,你就沦为一个打杂的了。第二,不论做什么项目,总归有些任务是很枯燥的,机械的。你终究要让你的组员去完成它,而一个专家是不会甘心被指派去做这种没有技术含量又不得不作的任务的。第三,专家势必要消耗更多的薪水,会使你增加成本。所以,一个团队,核心不在于配置最优的资源,而在于最优的配置资源。
  2. 必须在一切发生之前,制定规范。如果发生之后再制定,第一,损失已无法避免,第二,很容易让当事人有抵触心理,产生个人矛盾。在实际执行过程中,发生意外是最不意外的事情,所以一定要有准备,要时刻准备将事情拉回到规范中来。
  3. 要保持距离。比如,如果有心邀请另外一个组的组员过来帮忙,直接自己去的话,一旦当场被拒绝,就很难有回旋的余地。如果对方态度恶劣一些的话,还会影响以后的合作。此时不如找其他人出面,一个失败了还可以找其他人再试,就算发生矛盾也是他们两人之间的事,你本人还是有回旋的余地的。
  4. 一定要抓绩效考核。第一,它是最直观,最简单的考核方法。第二,它可以有效地提高团队的纪律性。
posted @ 2008-08-31 21:06 左右间 阅读(44) 评论(0) 编辑

2008年8月8日 #

以下内容以2007为准,不排除2003上有不同
每个Cell都可以设置Format,设置不同,处理的结果也会不一样。
情况1,没有设置Format。如果你输入的内容是日期,他会自动把这个Cell的Format变为日期型的,日期格式以当前的机器设置为准。这个时候,你直接以读数据库的方式去读的话,那个
你得到的是一个DateTime类型的值。

情况2,设置Format为日期类型,并指定固定的日期格式。你将得到的是一个DateTime类型的值。

情况3,设置Format为字符型,你将得到的是一个string类型的值。

举个实际的例子:

比如,你输入一个值:02\04\2008,本机的日期格式设置为英语(月-日-年)

情况1,你将得到一个DateTime:2008年02月04日

情况2。假设你Format为法语(日-月-年),你将得到一个DateTime:2008年04月02日

情况3,你将得到一个string:02\04\2008

所以,在处理的时候,要十分的小心,以避免出现日期不对的情况。为避免Excel做一些你不希望的操作,最好事先就给一个固定的Format,

posted @ 2008-08-08 13:44 左右间 阅读(417) 评论(0) 编辑

2008年8月2日 #

posted @ 2008-08-02 18:19 左右间 阅读(257) 评论(0) 编辑

2008年8月1日 #

posted @ 2008-08-01 14:27 左右间 阅读(596) 评论(0) 编辑

2008年7月30日 #

posted @ 2008-07-30 11:12 左右间 阅读(838) 评论(0) 编辑

2008年7月28日 #

posted @ 2008-07-28 11:32 左右间 阅读(111) 评论(0) 编辑

2008年5月29日 #

posted @ 2008-05-29 15:06 左右间 阅读(759) 评论(1) 编辑