演算法設計與分析第1章 演算法概述
阿新 • • 發佈:2018-12-14
第1章 演算法概述(窮舉演算法)
重要人物:Alan Turing(圖靈機)、Donald Knuth(TEX系統)
演算法:解決問題的一種方法或一個過程 特性:有窮性(Finiteness)、確定性(Definiteness)、可行性(effectiveness)、輸入(Input)、輸出(Output) 程式:演算法+資料結構
計算時間的漸進表示: 多項式時間演算法(polynomial time algorithm):O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) 指數時間演算法(exponential time algorithm):O(2^n) < O(n!) < O(n^n)
演算法複雜性:演算法所需要的計算機資源 時間複雜性:T(n) 空間複雜性:S(n) 漸近分析的記號:漸進上界記號O、漸進下界記號、非緊上界記號o、非緊下界記號、緊漸近界記號
窮舉演算法
例1. 雞翁一值錢5,雞母一值錢3,雞雛三值錢1。百錢買百雞,問雞翁、母、雛各幾何? Cock+Hen+Chick=100 Cock5+Hen3+Chick/3=100
程式碼:
#include<iostream>
#include<stdlib.h>
#include<math.h>
#include<cstdio>
#include<string>
#include <cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int main()
{
int x,y,z;
x=0;
while(x<=20)
{
y=0;
while(y<34)
{
z=100-x-y;
if((5*x+3*y+z*1.0/3)==100)
{
printf("Cock is %d,Hen is %d,Chick is %d\n" ,x,y,z);
}
y++;
}
x++;
}
return 0;
}
例2. Google方程式 有一個字元組成的等式:WWWDOT - GOOGLE = DOTCOM 1)每個字元代表一個0-9之間的數字; 2)WWWDOT、GOOGLE和DOTCOM都是合法的數字; 3)不能以0開頭。請找出一組字元和數字的對應關係,使它們互相替換,並且替換後的數字能夠滿足等式.
程式碼1:
/*
暴力搜尋(窮舉)
*/
#include<iostream>
#include<stdlib.h>
#include<math.h>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int main()
{
int w,d,o,t,g,l,e,c,m;
int A,B,C;
w=1;
while(w<=9)
{
d=1;
while(d<=9)
{
if(d==w)
{
d++;
continue;
}
o=0;
while(o<=9)
{
if(o==w||o==d)
{
o++;
continue;
}
t=0;
while(t<=9)
{
if(t==w||t==d||t==o)
{
t++;
continue;
}
g=1;
while(g<=9)
{
if(g==w||g==d||g==o||g==t)
{
g++;
continue;
}
l=0;
while(l<=9)
{
if(l==w||l==d||l==o||l==t||l==g)
{
l++;
continue;
}
e=0;
while(e<=9)
{
if(e==w||e==d||e==o||e==t||e==g||e==l)
{
e++;
continue;
}
c=0;
while(c<=9)
{
if(c==w||c==d||c==o||c==t||c==g||c==l||c==e)
{
c++;
continue;
}
m=0;
while(m<=9)
{
if(m==w||m==d||m==o||m==t||m==g||m==l||m==e||m==c)
{
m++;
continue;
}
A=w*100000+w*10000+w*1000+d*100+o*10+t;
B=g*100000+o*10000+o*1000+g*100+l*10+e;
C=d*100000+o*10000+t*1000+c*100+o*10+m;
if(A==(B+C))
{
cout<<"answer: "<<A<<" - "<<B<<" = "<<C<<endl;
}
m++;
}
c++;
}
e++;
}
l++;
}
g++;
}
t++;
}
o++;
}
d++;
}
w++;
}
return 0;
}
程式碼2:
/*
遞迴搜尋
*/
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
typedef struct tagcharitem //資料結構
{
char c;
int value;
} charitem;
charitem a[]= //初始化
{
{'W',-1},{'D',-1},{'O',-1},
{'T',-1},{'G',-1},{'L',-1},
{'E',-1},{'C',-1},{'M',-1}
};
int mark[10]; //標記陣列
void search(int cnt) //對字母進行搜尋 最後判斷下
{
if(cnt==10)
{
int sum1=a[0].value*1e5+a[0].value*1e4+a[0].value*1e3+a[1].value*1e2+a[2].value*10+a[3].value;
int sum2=a[4].value*1e5+a[2].value*1e4+a[2].value*1e3+a[4].value*1e2+a[5].value*10+a[6].value;
int sum3=a[1].value*1e5+a[2].value*1e4+a[3].value*1e3+a[7].value*1e2+a[2].value*10+a[8].value;
if(sum1-sum2==sum3)
cout<<sum1<<"-"<<sum2<<"="<<sum3<<endl;
return;
}
for(int i=0; i<=9; i++) //為字母賦值
{
if(mark[i]==0)
{
a[cnt].value=i;
mark[i]=1;
search(cnt+1);
a[cnt].value=-1;
mark[i]=0;
}
}
}
int main()
{
memset(mark,0,sizeof(mark));
search(0);
return 0;
}