博文

构造n阶魔方阵(2008-05-31 10:31:00)

摘要:构造n阶魔方阵 何谓魔方阵?
4 9 2
3 5 7
8 1 6
定义:由n*n个数字所组成的n阶方阵,具有各对角线,各横列与纵行的数字和都相等的性质,称为魔方阵。而这个相等的和称为魔术数字。若填入的数字是从1到n*n,称此种魔方阵为n阶正规魔方阵。   1.    n = 2k + 1(奇数时) (1)  1放在第一行的中间位置上; (2)  下一个数放在当前位置的上一行、下一列; (3)  若当前位置是第一行,下一个数放在最后一行;若当前位置是最后一列,下一个数放在第一列; (4)  若下一个数要放的位置上已经有了数字,则下一个数字放在当前位置的下一行,相同列。 根据此规则填充的3阶魔方阵如下: 8 1 6 3 5 7 4 9 2   2.    n = 4k(4的整数倍时) (1)  先将整个方阵划分成k*k个4阶方阵,然后在每个4阶方阵的对角线上做记号 (2)  由左而右、由上而下,遇到没有记号的位置才填数字,但不管是否填入数字,每移动一格数字都要加1 (3)  自右下角开始,由右而左、由下而上,遇到没有数字的位置就填入数字,但每移动一格数字都要加1 (2)后:                                  (3)后:       3.     n = 4k + 2
本法填制魔方阵时,先将整个方阵划成田字型的四个2 k + 1阶的奇数阶小方阵,并以下法做注记:
1,右半两个小方阵中大于k+2的行。
2,左半两个小方阵中( k + 1 , k + 1 )......

阅读全文(4119) | 评论:0

PKU题目分类,开始写解题报告(2008-05-31 10:09:00)

摘要:PKU题目分类,开始写解题报告  
对于思路的扩展以及应用都是具有好处的
初期:
一.基本算法:
(1)枚举. (poj1753,poj2965)
(2)贪心(poj1328,poj2109,poj2586)
(3)递归和分治法.
(4)递推.
(5)构造法.(poj3295)
(6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996)
二.图算法:
(1)图的深度优先遍历和广度优先遍历.
(2)最短路径算法(dijkstra,bellman-ford,floyd,heap+dijkstra)
(poj1860,poj3259,poj1062,poj2253,poj1125,poj2240)
(3)最小生成树算法(prim,kruskal)
(poj1789,poj2485,poj1258,poj3026)
(4)拓扑排序 (poj1094)
(5)二分图的最大匹配 (匈牙利算法) (poj3041,poj3020)
(6)最大流的增广路算法(KM算法). (poj1459,poj3436)
三.数据结构.
(1)串 (poj1035,poj3080,poj1936)
(2)排序(快排、归并排(与逆序数有关)、堆排) (poj2388,poj2299)
(3)简单并查集的应用.
(4)哈希表和二分查找等高效查找法(数的Hash,串的Hash)
(poj3349,poj3274,POJ2151,poj1840,poj2002,poj2503)
(5)哈夫曼树(poj3253)
(6)堆
(7)trie树(静态建树、动态建树) (poj2513)
四.简单搜索
(1)深度优先搜索 (poj2488,poj3083,poj3009,poj1321,poj2251)
(2)广度优先搜索(poj3278,poj1426,poj3126,poj3087.poj3414)
(3)简单搜索技巧和剪枝(poj2531,poj1416,poj2676,1129)
五.动态规划
(1)背包问题. (poj1837,poj1276)

阅读全文(5119) | 评论:6

pku3508 一个有趣的小学算术题(2008-05-22 09:39:00)

摘要: 题目链接:http://acm.pku.edu.cn/JudgeOnline/problem?id=3508 /*
一开始想用1n 2n到9n直接看能否整除11,结果TLE。
很纳闷,看别人才89ms,纸上一画才发现不就是小学算术题吗?
  a b c 0 
 +  a b c
 ---------- (a>0)
   3 5 3
*/
#include <stdio.h> #include <string.h> #define MAXSIZE 1000000 char h1[MAXSIZE+2],h2[MAXSIZE+2]; int len; int main() { int i,jin; int t=0; while(1) { scanf("%s",h1+1); len = strlen(h1+1); if(len==1 && h1[1]=='0') break; for(i=1;i<=len;i++) h1[i] -= '0'; h2[len+1] = 0; for(jin=0,i=len;i>=1;i--) { h2[i] = h1[i] - h2[i+1] - jin; if(h2[i]<0) { h2[i] += 10; jin = 1; } else jin = 0; } if(h2[1]==0) printf("%d. IMPOSSIBLE\n",++t); else { printf("%d. ",++t); for(i=1;i<=len;i++) printf("%d",h2[i]); printf("\n"); } } return 0; } ......

阅读全文(2283) | 评论:2

pku1351 动规——记忆化搜索(2008-05-22 09:35:00)

摘要:题目链接:http://acm.pku.edu.cn/JudgeOnline/problem?id=1351 /**********pku1351************
* 动规——记忆化搜索
* a[n][p][k][u]
* n: 统计了几个slot
* p: 当前取道那些值 按位存储p=7(0111)表示已经取到1,2,3
* k: 最后一个值
* u: 是否满足条件1
* 注意答案会超过32位整数
******************************/
#include <stdio.h> #include <memory.h> __int64 a[20][16][5][2]; int flag[5] = {0,1,2,4,8}; void init() { int i; memset(a,-1,sizeof(a)); for(i=0;i<=15;i++) { a[1][i][1][1] = a[1][i][2][1] = a[1][i][3][1] = a[1][i][4][1] = 0; a[1][i][1][0] = a[1][i][2][0] = a[1][i][3][0] = a[1][i][4][0] = 0; } a[1][1][1][0] = 1; a[1][2][2][0] = 1; a[1][4][3][0] = 1; a[1][8][4][0] = 1; } __int64 ado(int n,int p,int k,int u) { int t; if(n<=0) return 0; if(a[n][p][k][u]!=-1) return a[n][p][k][u]; a[n][p][k][u] = 0; if((p&flag[k])==0) return 0; /*p不包含k,直接返回0*/ t = p&~flag[k]; if(u==0) { if(k==1) { a[n][p][k][u] += ado(n-1,p,1,0) + ado(n-1,p,2,0) + ado(......

阅读全文(2478) | 评论:0