ぶんかつせんりゃく
7632 ワード
メモを取る!
(一)集計ソート:
(二)二分検索:
再帰でその中の分治思想を体得して、もちろんwhile循環で解決することができます!
(三)xのn次方:
ライブラリ関数の中のdouble pow(double x,double y)はもっと完璧で、指数は浮動小数点型であることができます.ここではdouble Pow(double x,int n)を手書きで書きます.
(四)フィボナッチ(Fibonacci)数列:
再帰は最も愚かな方法であり、反復は⊙(n)の複雑さであり、行列の高速べき乗は⊙(log(n))の複雑さに達することができる.
F(n)はn番目のフィボナッチ数にこのような関係があることを示す.
行列F(N+1)F(N)=行列1のN次方程式
F(N) F(N-1) 1 0
数学的帰納法で証明できる.したがって,結果は通常の行列の高速べき乗である.
(五)ストラソン行列乗算:
ネット上のやり方を参考にして,この行列乗算を書き換え,4次行列検証を用いた.
(一)集計ソート:
#include <stdio.h>
#include <stdlib.h>
#include <string>
typedef long long LL;
using namespace std;
/* T(n) = 2T(n/2) + ⊙(n) = nlog(n) */
void Merge_sort(int *A,int x,int y,int *t) /* x ,y */
{
if(y - x > 1){
int m = x + (y - x) / 2;
int p = x,q = m,i = x;
Merge_sort(A, x, m, t);
Merge_sort(A, m, y, t);
while(p < m || q < y){
if(q >= y || (p < m && A[p] <= A[q]))
t[i++] = A[p++];
else t[i++] = A[q++];
}
for(i=x; i<y; i++)
A[i] = t[i];
}
}
int main()
{
int t[15];
int s[] = {4, 1, 7, 6, 3, 8, 2, 5, 0, 9};
Merge_sort(s, 0, 10, t);
int i;
for(i=0; i<10; i++)
printf("%d ", s[i]);
printf("
");
return 0;
}
(二)二分検索:
再帰でその中の分治思想を体得して、もちろんwhile循環で解決することができます!
#include <stdio.h>
#include <stdlib.h>
#include <string>
typedef long long LL;
using namespace std;
/* T(n) = T(n/2) + ⊙(1) = log(n) */
int Binary_find(int key, int left, int right, int *a)
{
int mid = left + (right - left) / 2;
if(a[mid] == key) return mid;
else if(a[mid] > key) return Binary_find(key, left, mid - 1, a);
else if(a[mid] < key) return Binary_find(key, mid + 1, right, a);
}
int main()
{
int a[] = {1, 3, 4, 6, 7, 9, 12, 14, 23, 24};
int i;
int ans;
for(i=0; i<8; i++){
ans = Binary_find(a[i], 0, 7, a);
printf("%d
", ans);
}
return 0;
}
(三)xのn次方:
ライブラリ関数
#include <stdio.h>
#include <stdlib.h>
#include <string>
typedef long long LL;
using namespace std;
/* T(n) = T(n/2) + ⊙(1) = log(n) */
double f(double x, int n)
{
if(1 == n) return x;
int mid = (n>>1);
double s = f(x, mid);
if(n & 1) return s * s * x;
else return s * s;
}
double Pow(double x, int n)
{
if(0 == x && n > 0) return 0.0;
else if(0 == n) return 1.0;
else if(n > 0) return f(x, n);
else if(n < 0) return (1/f(x, -n));
}
int main()
{
double x;
int n;
while(~scanf("%lf%d", &x, &n)){
printf("%0.6lf
", Pow(x, n));
printf("%0.6lf
", pow(x, n));
}
}
(四)フィボナッチ(Fibonacci)数列:
再帰は最も愚かな方法であり、反復は⊙(n)の複雑さであり、行列の高速べき乗は⊙(log(n))の複雑さに達することができる.
F(n)はn番目のフィボナッチ数にこのような関係があることを示す.
行列F(N+1)F(N)=行列1のN次方程式
F(N) F(N-1) 1 0
数学的帰納法で証明できる.したがって,結果は通常の行列の高速べき乗である.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <iostream>
using namespace std;
int cnt;
/* */
LL Fibonacci(int n)
{
cnt++;
if(1 == n || 2 == n) return 1;
else return Fibonacci(n - 1) + Fibonacci(n - 2);
}
/* T(n) = ⊙(n) */
LL Fibonacci1(int n)
{
LL a[100000];
a[1] = a[2] = 1;
int i;
for(i=3; i<=n; i++)
a[i] = a[i - 1] + a[i - 2];
return a[n];
}
typedef struct
{
LL a[2][2];
}Matrix;
Matrix A, B;
Matrix Matrix_mul(Matrix X, Matrix Y)
{
Matrix tmp;
memset(tmp.a, 0, sizeof(tmp));
int i,j,k;
for(i=0; i<2; i++)
for(j=0; j<2; j++)
for(k=0; k<2; k++)
tmp.a[i][j] += X.a[i][k] * Y.a[k][j];
return tmp;
}
/* T(n) = ⊙(logn) */
LL Fibonacci2(int n)
{
A.a[0][0] = 1;
A.a[0][1] = 1;
A.a[1][0] = 1;
A.a[1][1] = 0;
B.a[0][0] = 1;
B.a[0][1] = 0;
B.a[1][0] = 0;
B.a[1][1] = 1;
while(n)
{
if(n & 1) B = Matrix_mul(B, A);
A = Matrix_mul(A, A);
n >>= 1;
}
return B.a[0][0];
}
int main()
{
int i;
int text = 4;
LL ans = Fibonacci1(text);
//long begtime = clock();
FILETIME beg,end;
GetSystemTimeAsFileTime(&beg);
for(i=0; i<100000; i++)
Fibonacci2(text);
GetSystemTimeAsFileTime(&end);
long time = (end.dwLowDateTime-beg.dwLowDateTime);
//long endtime = clock();
//cout<<endtime - begtime<<endl;
cout << time <<endl;
cout << ans <<endl;
}
(五)ストラソン行列乗算:
ネット上のやり方を参考にして,この行列乗算を書き換え,4次行列検証を用いた.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <iostream>
typedef long long LL;
using namespace std;
typedef int INT;
#define N 4
typedef struct matrix
{
INT a[N][N];
matrix()
{
memset(a, 0, sizeof(a));
}
}Matrix;
void Matrix_mul(const Matrix A, const Matrix B, Matrix &C)
{
memset(C.a, 0, sizeof(C.a));
int i,j,k;
for(i=0; i<2; i++)
for(j=0; j<2; j++)
for(k=0; k<2; k++)
C.a[i][j] += A.a[i][k] * B.a[k][j];
}
void Matrix_add(const int n, const Matrix A, const Matrix B, Matrix &C)
{
memset(C.a, 0, sizeof(C.a));
int i,j;
for(i=0; i<n; i++)
for(j=0; j<n; j++)
C.a[i][j] = A.a[i][j] + B.a[i][j];
}
void Matrix_sub(const int n, const Matrix A, const Matrix B, Matrix &C)
{
memset(C.a, 0, sizeof(C.a));
int i,j;
for(i=0; i<n; i++)
for(j=0; j<n; j++)
C.a[i][j] = A.a[i][j] - B.a[i][j];
}
void Strassen(INT n, const Matrix A, const Matrix B, Matrix &C)
{
Matrix A11, A12, A21, A22;
Matrix B11, B12, B21, B22;
Matrix C11, C12, C21, C22;
Matrix M1, M2, M3, M4, M5, M6, M7;
Matrix At, Bt, Mt, Mt1;
if(2 == n) Matrix_mul(A, B, C);
else{
n /= 2;
int i, j;
for(i=0; i<n; i++)
for(j=0; j<n; j++){
A11.a[i][j] = A.a[i][j];
A12.a[i][j] = A.a[i][j + n];
A21.a[i][j] = A.a[i + n][j];
A22.a[i][j] = A.a[i + n][j + n];
B11.a[i][j] = B.a[i][j];
B12.a[i][j] = B.a[i][j + n];
B21.a[i][j] = B.a[i + n][j];
B22.a[i][j] = B.a[i + n][j + n];
}
Matrix_sub(n, A12, A22, At);
Matrix_add(n, B21, B22, Bt);
Strassen(n, At, Bt, M1);
Matrix_add(n, A11, A22, At);
Matrix_add(n, B11, B22, Bt);
Strassen(n, At, Bt, M2);
Matrix_sub(n, A11, A21, At);
Matrix_add(n, B11, B12, Bt);
Strassen(n, At, Bt, M3);
Matrix_add(n, A11, A12, At);
Strassen(n, At, B22, M4);
Matrix_sub(n, B12, B22, Bt);
Strassen(n, A11, Bt, M5);
Matrix_sub(n, B21, B11, Bt);
Strassen(n, A22, Bt, M6);
Matrix_add(n, A21, A22, At);
Strassen(n, At, B11, M7);
/* sub_C */
Matrix_add(n, M6, M1, Mt);
Matrix_add(n, Mt, M2, Mt1);
Matrix_sub(n, Mt1, M4, C11);
Matrix_add(n, M5, M4, C12);
Matrix_add(n, M6, M7, C21);
Matrix_sub(n, M5, M3, Mt);
Matrix_add(n, Mt, M2, Mt1);
Matrix_sub(n, Mt1, M7, C22);
for(i=0; i<n; i++)
for(j=0; j<n; j++){
C.a[i][j] = C11.a[i][j];
C.a[i][j + n] = C12.a[i][j];
C.a[i + n][j] = C21.a[i][j];
C.a[i + n][j + n] = C22.a[i][j];
}
}
}
int main()
{
Matrix A, B, C;
A.a[0][0] = 1;
A.a[0][1] = 0;
A.a[0][2] = 2;
A.a[0][3] = 1;
A.a[1][0] = 0;
A.a[1][1] = 3;
A.a[1][2] = 1;
A.a[1][3] = 2;
A.a[2][0] = 0;
A.a[2][1] = 0;
A.a[2][2] = 2;
A.a[2][3] = 2;
A.a[3][0] = 2;
A.a[3][1] = 3;
A.a[3][2] = 0;
A.a[3][3] = 1;
B.a[0][0] = 2;
B.a[0][1] = 1;
B.a[0][2] = 0;
B.a[0][3] = 0;
B.a[1][0] = 0;
B.a[1][1] = 1;
B.a[1][2] = 1;
B.a[1][3] = 1;
B.a[2][0] = 1;
B.a[2][1] = 0;
B.a[2][2] = 2;
B.a[2][3] = 2;
B.a[3][0] = 3;
B.a[3][1] = 0;
B.a[3][2] = 2;
B.a[3][3] = 1;
Strassen(N, A, B, C);
int i,j;
for(i=0; i<N; i++){
for(j=0; j<N; j++)
printf("%-4d", C.a[i][j]);
printf("
");
}
return 0;
}