习题 1 1. 图论诞生于七桥问题。出生于瑞士的伟大数学家欧拉(Leonhard Euler,1707—1783) 提出并解决了该问题。七桥问题是这样描述的: 一个人是否能在一次步行中穿越哥尼斯堡(现 在叫加里宁格勒,在波罗的海南岸)城中全部 的七座桥后回到起点,且每座桥只经过一次, 图 1.7 是这条河以及河上的两个岛和七座桥的 草图。请将该问题的数据模型抽象出来,并判 北区 岛区 东区 南区 图 1.7 七桥问题 断此问题是否有解。 七桥问题属于一笔画问题。 输入:一个起点 输出:相同的点 1, 一次步行 2, 经过七座桥,且每次只经历过一次 3, 回到起点 该问题无解:能一笔画的图形只有两类:一类是所有的点都是偶点。另一类是只有二个 奇点的图形。 2.在欧几里德提出的欧几里德算法中(即最初的欧几里德算法)用的不是除法而是减 法。请用伪代码描述这个版本的欧几里德算法 1.r=m-n 2.循环直到 r=0 2.1 m=n 2.2 n=r 2.3 r=m-n 3 输出 m 3.设计算法求数组中相差最小的两个元素(称为最接近数)的差。要求分别给出伪代 码和 C++描述。 //采用分治法 //对数组先进行快速排序 //在依次比较相邻的差 #include using namespace std; int partions(int b[],int low,int high) { int prvotkey=b[low]; b[0]=b[low]; while (low=prvotkey) --high; b[low]=b[high]; while (low using namespace std; int main() { int a[]={1,2,3,6,4,9,0}; int mid_value=0;//将“既不是最大也不是最小的元素”的值赋值给它 for(int i=0;i!=4;++i) { if(a[i+1]>a[i]&&a[i+1]a[i+2]) { mid_value=a[i+1]; cout< using namespace std; int main() { double value=0; for(int n=1;n<=10000 ;++n) { value=value*10+1; if(value%2013==0) { cout<<"n 至少为:"< using namespace std; int main () { double a,b; double arctan(double x);//声明 a = 16.0*arctan(1/5.0); b = 4.0*arctan(1/239); cout << "PI=" << a-b << endl; return 0; } double arctan(double x) { int i=0; double r=0,e,f,sqr;//定义四个变量初 sqr = x*x; e = x; while (e/i>1e-15)//定义精度范围 { f = e/i;//f 是每次 r 需要叠加的方程 r = (i%4==1)?r+f:r-f; e = e*sqr;//e 每次乘于 x 的平方 i+=2;//i 每次加 2 }//while return r; } 7. 圣经上说:神 6 天创造天地万有,第 7 日安歇。为什么是 6 天呢?任何一个自然数的 因数中都有 1 和它本身,所有小于它本身的因数称为这个数的真因数,如果一个自然数的 真因数之和等于它本身,这个自然数称为完美数。例如,6=1+2+3,因此 6 是完美数。神 6 天创造世界,暗示着该创造是完美的。设计算法,判断给定的自然数是否是完美数 #include using namespace std; int main() { int value, k=1; cin>>value; for (int i = 2;i!=value;++i) { while (value % i == 0 ) { k+=i;//k 为该自然数所有因子之和 value = value/ i; } }//for if(k==value) cout<<"该自然数是完美数"<1) return 3*T(n-1); } (2) int T(int n) { if(n==1) return 1; else if(n>1) return 2*T(n/3)+n; } 5. 求下列问题的平凡下界,并指出其下界是否紧密。 (1)求数组中的最大元素; (2)判断邻接矩阵表示的无向图是不是完全图; (3)确定数组中的元素是否都是惟一的; (4)生成一个具有 n 个元素集合的所有子集 (1) Ω(n) 紧密? (2) Ω(n*n) (3) Ω(logn+n)(先进行快排,然后进行比较查找) (4) Ω(2^n) 7.画出在三个数 a, b, c 中求中值问题的判定树。 是 a using namespace std; int main() { long double result=1; double j=1; for(int i=1;i<=64;++i) { j=j*2; result+=j; j++; } cout< using namespace std; int BF(char S[], char T[]) { int index = 0; int i = 0, j = 0; while ((S[i] != '\0') && (T[j] != '\0')) { if (S[i] == T[j]) { i++; j++; } else { ++index; i = index; j = 0; } } if (T[j] == '\0') return index + 1; else return 0; } int main() { char s1[19]="ababcabccabccacbab"; char s2[7]="abccac"; cout<< BF( s1, s2) < using namespace std; void GetNext(char T[ ], int next[ ]) //求模式 T 的 next 值 { int i, j, len; next[0] = -1; for (j = 1; T[j]!='\0'; j++) //依次求 next[j] { for (len = j - 1; len >= 1; len--) //相等子串的最大长度为 j-1 { for (i = 0; i < len; i++) //依次比较 T[0]~T[len-1]与 T[j-len]~T[j-1] if (T[i] != T[j-len+i]) break; if (i == len) { next[j] = len; break; } }//for if (len < 1) next[j] = 0; //其他情况,无相等子串 }//for } int KMP(char S[ ], char T[ ]) { int i = 0, j = 0; int next[80]; GetNext(T, next); while (S[i] != '\0' && T[j] != '\0') { if (S[i] == T[j]) { i++; j++; } else { j = next[j]; if (j == -1) {i++; j++;} //求 T 在 S 中的序号 //假定模式最长为 80 个字符 } } if (T[j] == '\0') return (i - strlen(T) +1); else return 0; } //返回本趟匹配的开始位置 int main() { char s1[]="ababcabccabccacbab"; char s2[]="abccac"; cout< using namespace std; int main() { int n;//分子 int m;//分母 int factor;//最大公因子 int factor1; cout<<"输入一个真分数的分子与分母: "<>n>>m; int r = m % n;//因为是真分数 所以分母一定大于分子 factor1=m; factor=n; while (r != 0) { factor1 =factor; factor = r; r = factor1% factor; } cout<<"输出该真分数的最简分数: "<<(n/factor)<<"/"<<(m/factor)< using namespace std; int main() { int a[9]={5,6,2,8,4,3,7,4,8}; int result=0; //result 为题目要求的各位之和 for(int i=0;i!=9;++i) { if(i%2==0) result+=a[i]; //i 为偶数位时,结果加上其对应数组数的本身 else result+=a[i]*10; //i 为奇数位时,结果加上对应数组数的 10 倍 } if(result%11==0) cout<<"该整数能被 11 整除"< using namespace std; int square(int x) { return x*x; } //用递归思想 int resultmod(int a, int n) { if(n== 0) return 1; if(n%2 == 0) return square(resultmod(a, n/2));//n 为偶数的时,取 n 的一半防止溢出 else return a*resultmod(a, n-1);//n 为奇数时,取 n-1; } int main() { int a, n, m; cout<<"请输入 a,n, m: "<<" "; cin>>a>>n>>m; cout< using namespace std; void deletere(int a[],int N) { int b[100]={0}; int i,k; k=0; static int j=0; for(i=0;i using namespace std; int main() { int a[]={1,2,1,5,3,2,9,4,5,5,3,5}; int i,j; for( i=0;i<12;i++) { for(j=0;j using namespace std; int partions(int l[],int low,int high) { int prvotkey=l[low]; l[0]=l[low]; while (low=prvotkey) --high; l[low]=l[high]; while (low using namespace std; const int N = 20; void swap_ab ( int *p , int *q ) { int tmp = *p; *p = *q; *q = tmp; } void process ( int a[], int n ) { int *p, *q; p = q = a; while ( p != a+n-1 ) //p 向前遍历,直到便利完毕 { if ( *(p+1) < *p ) { q = p+1; while ( *q < *(q-1) ) { swap_ab ( q, q-1 ); --q; //q 指针后移 } } //if ++p; } //while } int main() { int a[N] = { 0, 2, 1, 2, 0, 1, 0, 2, 2, 1, 0, 1, 2, 1, 1, 0, 0, 1, 1, 2}; //待处理的数组 cout << "处理后的数组序列: " < using namespace std; int main() { int x,y,x0,y0; int summax=0,temp=0; for(x0=0;x0<=4;++x0) { for(y0=0;(x0+y0<=4)&&(x0+3*y0<=6);++y0) temp=3*x0+5*y0; if(temp>=summax) { summax=temp; x=x0;//符合 sum 最大值的 x y=y0;//符合 sum 最大值得 y } }//for cout<<"x= "<