随笔分类 - 常用算法备份
摘要:问题(简化过了):偶数矩阵定义: 一个n*n矩阵中, 每个元素的上下左右之和为偶数.给定n, 穷举(或算出1个数最多/最小等)偶数矩阵.分析:比较直接的想法是暴力穷举, n^n. 但这样n=30左右就吃不消了.优化解法: 遍历第一行所有情况(n^2), 之后第二行可根据第一行算出来, 依次类推. 运算规模只有 2*(n^2)#include #include using namespace std;#define L 5bool matrix[L][L];bool minMt[L][L];int n = L;bool val(int i, int j) { int sum = 0; ...
阅读全文
摘要:有n个正整数组成一个 序列。给定整数s, 求长度最短的连续序列, 使他们的最大和大于或等于S。书中给出3种思路, 先上图:A. 暴力枚举起点和终点,并且依次求和。 复杂度n3B. 如图所示,A方法中曲线部分包括许多重复的区间, 可以通过保存前缀来降低一些复杂度, 得到n2算法。 令B[i] = A[0]+A[1]+...A[I], 则B[j] - B[i] = A[i] +...+A[j], 也就是可以在O(1)时间内计算出子序列和。 此方法本质是:通过空间换时间省去计算过程。 但此方法也要枚举起点和终点,复杂度不会低于n2.C. 考虑只枚举终点。对于点 j, 只需要找到满足 B[j]-B..
阅读全文
摘要:情景: 在周长为1000的圆周上均匀放n个红点, m+n个黑点,如何表示每个红点和周围最近的黑点的距离?分析:不管周长是多少,先假设周长是1, 则红点之间间距是1/n 这样(m+n)个黑点之间的距离是 1/(m+n). 为了防止损失精度, 把它们同时乘以(m+n), 则红点间距 (m+n)/ n , 黑点间距1. ( 反过来想,假设设较小的间距为1)。 这样, 将某个红点四舍五入后得到的值就是离它最近的黑点。将它们之间距离放大为原比例即可。注意精度。 示意: 1--------2--------3--------4--------5--------6 ----1....
阅读全文
摘要:算法的思想: 对于不超过n的每个非负整数p, 删除2p,3p,4p....., 当处理完所有数之后, 还没被删除的就是素数. 用vis[i]表示已经被删除的数.简单的算法可以表示成:for ( int i = 2; i <= n; i++) { for ( int j = i*2; j <= n; j+=i ) vis[j] = 1;}因为小于n的素数的个数小于等于lgn ( 相关证明可以在初等数论第一章中找到 ), 可以缩短外层循环. int m = sqrt(n + 0.5); for ( int i = 2; i <= m; i++) { if (!v...
阅读全文
摘要:给出这样一个除法表达式X1/X2/X3../Xn:输入X1 X2 X3 X4…Xn, 判断是否可以通过添加括号使表达式的值为整数.解析:X1/X2/X3../Xn = X1 / (X2*X3*X4..Xn)可以推出(X2一定在分母位置):X1/X2/X3../Xn = X1 / ( X2 / X3 / X4.../Xn ) = ( X1*X3 *X4..Xn ) / X2问题就变成了求( X1*X3 *X4..Xn ) 能不能被X2整除.方法1: 高精度运算.方法2: 利用唯一分解定理, 把X2分解成若干素数相乘形式, 然后依次判断每个素数是否是( X1*X3 *X4..Xn )的约数(比较这
阅读全文
摘要:百度百科:http://baike.baidu.com/view/20089.htm维基百科:http://zh.wikipedia.org/wiki/Hash
阅读全文
摘要:1. 物品无限背包问题.有n种物品, 每种都有无穷多个, 第i种物品体积为Vi, 重量为Wi. 选一些物品装到一个容量为C的背包里, 使得背包内物品总体积不超过C的前提下重量尽量大.1<n<=100,1<=Vi<=C<=10000,1<=Wi<=10^6[分析] 带权的DAG最长路径问题, 把代码中的+1改为+W[i]即可.2. 0-1背包问题只凭"剩余体积"这个状态, 无法得知该物体是否被用过.这里引入"多阶段决策的最优化": 用d(i,j)表示当前在第i层, 剩余容量为j时接下来的最大重量和.则d(i,j)=
阅读全文
摘要:从上往下求和, 求最大和的路径. 1 3 24 10 1分析: 从下向上求和附代码和运行结果:递推计算和递归求和, 它们都会把前一步的计算结果保存下来int n = 3;int a[4][4] = {1,0,0,0,3,2,0,0,1,10,1,0,4,3,2,20};int s[4][4];void d(int i, int j) { for ( int i = n; i >= 0; i-- ) for (int j = 0; j <=n; j++ ) s[i][j] = a[i][j] + (i == n ? 0 : (s...
阅读全文
摘要:有一个2^k*2^k的方格棋盘, 恰有一个方格是黑色的, 其它为白色.用包含3个方格的L形牌覆盖所有白色方格.黑色方格不能被覆盖,且白色方格不能被两个或更多的牌覆盖.[分析] 由2^k*2^k很容易想到分治, 考虑用递归来解决.我的代码:#define SIZE 16char M[SIZE][SIZE];int P[2];char Color[4] = {'+','-','~','.'};/* + --- 0+ ++ + --- 1 + + --- 2+ + + + --- 3+ */bool containsPoint( int
阅读全文
摘要:int main () { double a, c; double x = 0, y = 100,m; int b; scanf("%lf%d%lf",&a,&b,&c); while( y - x > 1e-5) { printf("%f ", y); m = x + (y-x)/2; double f = a; for ( int i = 0; i < b; i++ ) f += f*m/100-c; if (f<0) x = m; else y = m; } print...
阅读全文
摘要:void partation(int size) { if (size == 1) { A[0][0] = 1; return; } partation(size/2); for ( int i = 0; i < size/2; i++ ) { for ( int j = 0; j < size/2; j++ ) { A[i+size/2][j] = A[i][j] + size/2; A[i][j+size/2] = A[i][j] + size/2; A[i...
阅读全文
摘要:利用hash来进行节点判重typedef int State[9];const int MAXSTATE = 1000000;State st[MAXSTATE], goal;int dist[MAXSTATE];int vis[36288], fact[9];const int dx[] = {-1,1,0,0};const int dy[] = {0,0,-1,1};const int MAXHASHSIZE = 1000003;int head[MAXHASHSIZE], next[MAXHASHSIZE];int hash(State& s) { int v = 0; fo..
阅读全文
摘要:使用单位分数的和表示有理数。 例如 2/3 = 1/2 + 1/6; 加数不能有重复。0<a<b<1000。(有一个条件这里还没实现: 如果加数个数相同, 则最小分数越大越好。)此题目解答树宽度和深度都没有上限,不能直接用bfs或者dfs。解决方案是采用迭代加深搜索:从小到大枚举深度上限。int a, b;int tree[1000];bool dfs(int deep, int cb, int sa, int sb ) { tree[deep] = cb; int _a = sb + cb * sa; int _b = cb * sb; // 同一层向右平移, 找一个...
阅读全文
摘要:输入两个整数n1, n2. 用 最少的四则运算从n1得到n2. 例如: 输入2,5, 则 2 / 2 = 1, 1 + 2 = 3, 3 + 2 = 5. 运算结果为 DIV, ADD, ADD.(好吧我偷懒把题目简化了。。)因为运算步骤可能无限长,本题的解答树是无限大的, 此题不能用回溯来解。本题要求最短过程,利用宽度优先遍历解答树。int n1, n2;char operators[4][4] = {"ADD","SUB","DIV","MUL"};int sequence[100];void bfs() {
阅读全文
摘要:回溯法, 全排列生成问题, 枚举量不超过 n! 个.#define S 4int n = S;int tot = 0;int C[S] = {0};void m_search(int cur) { if ( cur == n ) { tot += 1; for ( int i = 0; i < n; i++ ) printf("%d ", C[i]); printf("\n"); return; } for ( int i = 0; i < n; i++ ) { int ok = 1; C[cur] = i...
阅读全文
摘要:#define L 5int N[L] = {1,2,3,4,5};void print_permutation(int n, int *a, int cur) { if ( cur == n ) { for ( int i = 0; i < n; i++ ) { printf("%d ", a[i]); } printf("\n"); } else { for ( int i = 0; i < n; i++ ) { int has = 0; for ( ...
阅读全文
摘要:找一条从起点到终点的最短移动序列。首先计算出起点到每个节点的最短距离(未完待续)#define SIZE 6int mat[SIZE][SIZE], vis[SIZE][SIZE];int que[SIZE*SIZE][2];int addNode(int x0, int y0, int x, int y, int rear) { if (( x < 0 ) || ( y < 0 ) || ( x >= SIZE ) || ( y >= SIZE )) return rear; if (( mat[x][y] < 0 )||( vis[x][y])) return
阅读全文
摘要:输入一个n*n的黑白图像,(1表示黑色,0表示白色),统计其中相连块的个数。例如:100100001010000000110000111000010100上面矩阵所示图形中有3块黑色图像。解答: 用递归求解。从每个未被访问过的黑格子除法, 递归访问所有相连的八个黑格子。#define SIZE 6int mat[SIZE][SIZE], vis[SIZE][SIZE];void dfs( int x, int y) { if (( x < 0 ) || ( y < 0 ) || ( x >= SIZE ) || ( y >= SIZE )) return; if ((
阅读全文
摘要:typedef struct TNode{ int have_value; int v; struct TNode *left, *right;} Node;Node *root;Node* newNode() { Node *u = (Node *)malloc(sizeof(Node)); if ( u != NULL ) { u -> have_value = 0; u -> left = u -> right = NULL; } return u;}void addNode( int v ) { Node *n...
阅读全文
摘要:void merge( vector<int> &v1, int low, int mid, int high ) { vector<int> v2(L); int i = low, j = mid + 1, k = low; while ( i <= mid && j <= high ) { if ( v1[i] <= v1[j] ) { v2[k++] = v1[i++]; } else { v2[k++] = v1[j++]; } } while ( i <= mid ) ...
阅读全文

浙公网安备 33010602011771号