湘潭大学软件工程算法设计与分析考试复习笔记(六)

文章目录

回顾

说明

这篇笔记是关于 40 分的程序填空的。

前面涉及代码的部分

湘潭大学软件工程算法设计与分析考试复习笔记(二):这篇博客里面有一些代码,可以选择性地记一记。

因为代码填空涉及的内容比较广泛,下面主要是从ppt里面摘录出来。

第一章

没有代码填空,非常轻松。

第二章

汉诺塔问题

cpp 复制代码
void Hanoi(int n, int Fr, int To, int As)
          {
               if  (n > 0) {
                    Hanoi(n--1, Fro, Ass, To);
                    Move(Fro, To);
                    Hanoi(n--1, Ass, To, Fro)}
           }

正整数的划分

cpp 复制代码
q(n, m) { 
       if (n < 1) || (m < 1)      return 0;
       if (n == 1) || (m == 1)  return 1;
       if (n == 1) || (n < m)    return 1 + q(n, n--1);
       return q(n, m--1) + q(n--m, m);  }

Hilbert图案

cpp 复制代码
A(i) { 
   if  (i > 0) { D(i -- 1); x = x -- h;  ploting(x, y) ; 
      A(i -- 1);   y = y -- h;  ploting(x, y) ;
      A(i -- 1);   x = x + h;  ploting(x, y) ;
       B(i -- 1); }}
  //*ploting(x, y)是从画笔现行坐标到坐标(x, y)画条直线

Koch 曲线

cpp 复制代码
Koch(L, i) { //*L为长度,i为级数
  if (i == 0) Line(L) //*i为0,画条长为L的线段
  else {Koch(L/3, i -- 1);
           Turn(60);  Koch(L/3, i -- 1);
           Turn(--120);  Koch(L/3, i -- 1);
           Turn(60);  Koch(L/3, i -- 1);}}
Draw-Koch(L, θ, n) {//*将角度初始化为θ;
     Turn(θ);  Koch(L, n);}//*然后再画曲线。

二分搜索有序表

cpp 复制代码
Binary-Search(L, n, z)
{k = 1; m = n; //*k和m分别为搜索部分的首和尾
 flag = 0; //*找到标志初始为0
 while (k <= m && flag = 0) {
     j = (k + m) / 2 ; //*取中点下标 
    if (z == L[j]) flag = 1 //* 找到了标志为1
  else if (z < L[j]) m = j -- 1 //*小于中点,尾前移
      else k = j + 1 //*大于中点,首后移
} 

一维最接近点对算法

有一些特殊符号显示不出来。所以这里把课件的截图也放在这儿了。

cpp 复制代码
bool Cpair1(S, d)
{
   n = |S|;
   if (n < 2) { d = ∞; return false }
   m = S中各点的坐标的中位数;
   构造S1和S2; // S1={xS | xm}, S2={xS | x>m}
   Cpair1(S1, d1); 
   Cpair1(S2, d2);  //分别求S1和S2的最接近点对
   p=max{S1}; q =min{S2}; d = mim{d1, d2, q -- p};
   return true 
}

平面最接近点对的算法

不是那种非常标准的代码,应该是为了方便我们理解写的伪代码

第三章

Prim算法的实现

cpp 复制代码
Prim(int n, Type **c) {
	int j = 1; s[j] = true; 
	for (int i = 2; i <= n;  i++) { 
		closest[i] = 1; 
		lowcost[i]=c[1][i];
		s[i]=false;
	}
	for (int i = 1; i < n;  i++) {
		min= inf; 
		for (int k = 2; k <= n;  k++) {
    		if (lowcost[k]<min&&!s[k]){
    			min = lowcost[k]; 
    			j = k;
    		} 
	s[j] = true;                         
	for (int k = 2; k <= n;  k++) {
    	if (c[j][k]< lowcost[k]&&!s[k]){
    		lowcost[k] = c[j][k]; 
    		closest[k] = j;
       }
    }
} 

Kruskal算法的实现

cpp 复制代码
Kruskal(int n, **e)  {
  Sort(e, w); //将边按权重从小到大排序
  initialize(n); //初始时每个顶点为一个集合
  k = 1; //k累计已选边的数目,
  j = 1;  //j为所选的边在e中的序号
  while (k < n) //选择n -- 1条边
    {a = Find(e[j][u]); b = Find(e[j][v]); 
   //找出第j条边两个端点所在的集合
     if (a != b) {t[k++] = j; Union(a, b)}
   //若不同,第j条边放入树中并合并这两个集合
     j++ }} //继续考察下一条边

Dijkstra 算法

第四章

消除重复的矩阵连乘算法

最优三角剖分的算法

cpp 复制代码
Void MinWeightTriangulation(int n, Type **t, int **s)
 {  for (int i = 1; i <= n; i++) t[i][i] = 0; 
     for (int r = 2; r <= n; r++) 
        for (int i = 1; i <= n -- r +1; i++) {
           int j = i + r -- 1;
           t[i][j] = t[i+1][j] + w(i--1, i, j);
           s[i][j] = i; 
           for (int k = i + 1; k < j; k++) {
              int u = t[i][k] + t[k+1][j] + w(i--1, k, j); 
              if (u < t[i][j]) {t[i][j] = u; s[i][j] = k;}
}}} //程序中红色的部分为改动的地方

动态规划法求序列相似性

第五章

树搜索的一般形式

cpp 复制代码
SearchTree(Space T)//表L用来存放待考察的结点
{unfinish = true; L = T.initial; 
// unfinish表示搜索未结束,先将初始状态放入L
while (unfinish || L≠Φ) {
     a = L.first; //从L中取出第一个元素
     if (a is goal) unfinish = false //若a是终态则结束
 else Control-put-in(L, Sons(a));
} //否则,将a的儿子们以某种控制方式放入L中

迭代回溯法的一般形式

用末尾标记的迭代回溯

数字的全排列





n 皇后





TSP 递归回溯






用回溯法解0-1背包问题

cpp 复制代码
Try(s){
 for (i = 0; i < 2; i++)
   if  (Accept(i)) {
        Record(s, i);
       if (s = = n) {if  ( better ) TakeNewChoice( );}  
   else Try(s+1);
       Move-off(s, i);}
 return } 

0-1背包问题的迭代实现

cpp 复制代码
Backtrack(Tree T) {
 j = 1; L.Push(--1, 0, 1);
  while (L≠Φ) {
    a = L.Pop( ); 
    if (a = = --1) {Move-off(j, N[j]); j-- --;}
else if (W+w[j]*a <= C) {Record(a);
        if (j = = n ) {if (V < NV) TakeNewChoice( );}
 else {j++; L.Push(--1, 0, 1);}
}}}

第六章

求传递闭包的Warshall算法

cpp 复制代码
for (i = 1; i <= n; i++)
         for (j = 1; j <= n; j++)
              if (M[j][i] == 1) 
                    for (k = 1; k <= n; k++)
                          M[j][k] = M[j][k] + M[i][k]

ppt 上面只有这个代码。之后会补充一些,在博客的最后面。

第七章

直接用概率进行数值计算

cpp 复制代码
double Darts (int n) {double x, y;  int k = 0; 
  static RandomNumber dart;
  for (int i=1; i<=n; i++) {x=dart.fRandom();   
     y=dart.fRandom(); if (y<=f(x)) k++;}
  return k/double(n); }

"洗牌"后的快速排序

cpp 复制代码
void Shuffle(Type a[], int n) { //随机洗牌算法
   static RandomNumber md;
   for (int i = 1; i < n; i++) {
         int j = md.Random(n -- i + 1) + i;
         Swap(a[i], a[j]); }}
Void QuiksortByShuffle(Type a[], int n) {
    Shuffle(a, n); //将数组a洗牌
    Quiksort(a, n); }

随机抽样

cpp 复制代码
int RandomSampling(S[n], A[m], m) {
  mark[1..n] = False;  count=0;
  while(count < m) {
      r = random(1, n);
      if (mark[r] == False) {
          count++;
          A[count]=S[r];
          mark[r]=True; }}}

Fermat素数测试法

cpp 复制代码
Bool Fermat_Prime(int n) {
   a = 2; power = n -- 1; other = 1;
  while(power > 1)  {
    if (power % 2 = = 1) {other *= a; other %= n;}
    power /= 2;   a = a * a  %  n;}
  if  (a * other  %  n == 1) return True;
  return False;
}

Miller-Rabin素数判定概率算法

cpp 复制代码
Bool  Miller_Rabin_Prime(int n){
 b[1 .. m] = RandomSampling(n, m); 
 /*随机选取m个大于1小于n的无重复的自然数
for (j = 1; j <= m;  j++)
      if (W(b[j]) 满足)  return False;
 return True;
}
若m = 100,则n不是素数的概率小于1/2100。

模拟退火算法的框架

cpp 复制代码
k = 0; i = i0; t = t0; //初始化
while (不满足停止准则) {
   Gen(Si); //产生i的邻域Si,|Si|=Lk
   for (j∈Si) //用Metropolis准则对Si中的
        if (f(i) < f(j)) i = j; //每个状态j检测是否可替代i
     else if (exp((f(i) -- f(j))/ t) > random(0, 1)) i = j;
   k = k + 1; t = tk; // 降温;进入下一轮迭代
 }       

第八章

没有代码

补充

最佳调度

cpp 复制代码
long f(int n) {
    if (n < 2) return n;
    long sum = 1;
    for (int i = 1 ; i <= n - 1; i++)
        sum += f(i);
    return sum;
 }

备忘录方法

cpp 复制代码
 Long dp[max]
 long f1(int n) {
    dp[1] = 1;
    dp[2] = 2;
    if (n <2) { 
        return dp[n];
    }
    if (dp[n] > 0) return dp[n];
    long sum = 1;
    for (int i = 1 ; i <= n - 1; i++)
        sum += f1(i);
    dp[n] = sum;
    return dp[n];
 }

上台阶

cpp 复制代码
#include<iostream>
#include<cmath>
using namespace std;
int dp[107];
int main() {
	int n, m;
 	cin >> n >> m;
 	dp[0] = 1;
 	for (int i = 1; i <= n; i++) {
 		for (int j = 1; j <= m; j++) {
			 if (i < j)break;
 			dp[i] += dp[i - j];
 		}
 	}
 	cout << dp[n];
 	return 0;
}
相关推荐
maknul24 分钟前
【学习笔记】AD智能PDF导出(装配文件)
笔记·学习·pdf
sjsjs111 小时前
【数据结构-表达式解析】【hard】力扣224. 基本计算器
数据结构·算法·leetcode
C++忠实粉丝1 小时前
计算机网络socket编程(6)_TCP实网络编程现 Command_server
网络·c++·网络协议·tcp/ip·计算机网络·算法
坊钰1 小时前
【Java 数据结构】时间和空间复杂度
java·开发语言·数据结构·学习·算法
pq113_61 小时前
ftdi_sio应用学习笔记 4 - I2C
笔记·学习·linux驱动·ftdi_sio
武昌库里写JAVA1 小时前
一文读懂Redis6的--bigkeys选项源码以及redis-bigkey-online项目介绍
c语言·开发语言·数据结构·算法·二维数组
禊月初三1 小时前
LeetCode 4.寻找两个中序数组的中位数
c++·算法·leetcode
学习使我飞升1 小时前
spf算法、三类LSA、区间防环路机制/规则、虚连接
服务器·网络·算法·智能路由器
庞传奇2 小时前
【LC】560. 和为 K 的子数组
java·算法·leetcode
SoraLuna2 小时前
「Mac玩转仓颉内测版32」基础篇12 - Cangjie中的变量操作与类型管理
开发语言·算法·macos·cangjie