曼德勃罗特集
2010年8月12日 02:44 | Comments(1558) | Category:C语言 | Tags:数学 分形 高维度
#include <stdio.h> int main(void) { double realCoord, imagCoord; double realTemp, imagTemp, realTemp2, arg; int iterations; for(imagCoord = 1.2; imagCoord >= -1.2; imagCoord -= 0.05) { for(realCoord = -0.6; realCoord <= 1.77; realCoord += 0.03) { iterations = 0; realTemp = realCoord; imagTemp = imagCoord; arg = realCoord*realCoord + imagCoord*imagCoord; for(; arg<4 && iterations<40; ++iterations) { realTemp2 = realTemp*realTemp - imagTemp*imagTemp - realCoord; imagTemp = 2*realTemp*imagTemp - imagCoord; realTemp = realTemp2; arg = realTemp*realTemp + imagTemp*imagTemp; } switch (iterations % 4) { case 0: putchar('.'); break; case 1: putchar('o'); break; case 2: putchar('O'); break; case 3: putchar('@'); break; } } putchar(10); } return 0; }
N皇后问题
2010年8月10日 00:22 | Comments(22) | Category:C语言 | Tags:c 二进制 位运算 数学
#include <stdio.h> static int upperlim, sum; void binqueen(int row, int ld, int rd) { int pos, p; if(row != upperlim) { pos = upperlim & ~(row | ld | rd); while (pos) { p = pos & -pos; pos -= p; binqueen(row+p, (ld+p)<<1, (rd+p)>>1); } } else sum++; } int main(void) { int n; scanf("%d", &n); upperlim = (1<<n) - 1; binqueen(0, 0, 0); printf("%d", sum); return 0; }
卡特兰数
2010年8月08日 23:29 | Comments(12) | Category:C语言 | Tags:c 数学 递归式 高精度 排列组合
#include <stdio.h> int C[101][101], len[101]; int main(void) { int i, j, r, t, l; C[0][0] = 1; len[0] = 1; l = 1; //长度 for(i = 1; i <= 100; ++i) { for(j = 0; j < l; ++j) //乘法 C[i][j] = C[i-1][j] * (4*i-2); for(r=j = 0; j < l; ++j) { t = C[i][j] + r; C[i][j] = t % 10; r = t / 10; } while(r) C[i][l++] = r % 10, r /= 10; for(j = l-1, r = 0; j >= 0; --j) //除法 { t = r*10 + C[i][j]; C[i][j] = t / (i+1); r = t % (i+1); } while(!C[i][l-1]) --l; len[i] = l; } for(i = 1; i <= 100; ++i) { printf("%d:", i); for(j = len[i]-1; j >= 0; --j) printf("%d", C[i][j]); putchar(10); } return 0; }
求一个数是第几个排列数
2010年8月06日 00:47 | Comments(81) | Category:C语言 | Tags:c 数学 康托 排列组合 转换
根据康托展开公式:
a[i]为第i个数比后面的都小的个数。
#include <stdio.h> #include <string.h> int FAC[10] = {1,1,2,6,24,120,720,5040,40320,362880}; int CantorExp(char *s, int n) { int i, j, t, num = 0; for(i = 0; i < n; ++i) { t = 0; for(j = i+1; j < n; ++j) if(s[j] < s[i]) ++t; num += FAC[n-i-1]*t; } return num+1; } int main(int argc, char *argv[]) { char s[] = "1324"; //输入一个排列数的字符串序列 printf("%d", CantorExp(s, strlen(s))); return 0; }
求平面最近点对
2010年8月04日 03:33 | Comments(44) | Category:C语言 | Tags:c 数学 分治 平面点集
对于平面上N个点,求其中两个距离最近的点。输入格式:点的个数N,然后是N个坐标即可计算出。
#include <stdio.h> #include <math.h> #include <assert.h> #include <stdlib.h> struct pos {double x, y;}; typedef struct pos Pos; Pos p[100000]; int d[100000]; double eps = 0.00001; int cmp_x(const void *p, const void *q) { double tmp=((Pos*)p)->x-((Pos*)q)->x; if(tmp>0) return 1; else if(fabs(tmp)<eps) return 0; else return -1; } double Dest(Pos p2, Pos p1) { return ((p2.y-p1.y)*(p2.y-p1.y)+(p2.x-p1.x)*(p2.x-p1.x)); } double Min(double a, double b) { return a < b ? a : b; } int cmp(const void *a, const void *b) { return(*(int *)a-*(int *)b); } double NSP(int left, int right) { double m1, m2, m3 , res; int i, j, ix, mid; if(right - left == 1) return Dest(p[right], p[left]); else if(right - left == 2) { m1 = Dest(p[left], p[left+1]); m2 = Dest(p[left], p[left+2]); m3 = Dest(p[left+1], p[left+2]); return Min(m1, Min(m2, m3)); } mid = (left+right)/2; res = Min(NSP(left, mid), NSP(mid+1, right)); ix = 0; for(i = mid; i>=left && p[mid].x-p[i].x < res; --i) d[ix++] = i; for(i = mid+1; i<=right && p[i].x-p[mid+1].x < res; ++i) d[ix++] = i; qsort(d, ix, sizeof(d[0]), cmp); for(i = 0; i < ix; ++i) for(j = i+1; j<ix && j<i+4 && p[d[j]].y-p[d[i]].y < res; ++j) res = Min(res, Dest(p[d[j]], p[d[i]])); return res; } int main(void) { int N, i; while(scanf("%d", &N), N) { assert(N!=1 && N<100000); for(i = 0; i < N; ++i) scanf("%lf %lf", &p[i].x, &p[i].y); qsort(p, N, sizeof(p[0]), cmp_x); printf("%.2lf\n", sqrt(NSP(0, N-1))); } return 0; }
用的是分治法。