算法期末备考-第1练-分支界限法

算法期末备考-第1练 

考虑到 同学们针对备考 算法无从下手,同时算法是最后一门考试科目,可能复习不太好就去考试了。

从今天开始每天进行一练,希望大家每天花上至少一个小时来复习,只要大家重视起这门课,就不会挂科。

 

算法是一门理解为基础的课程。

“理解是最好的记忆”

不要背代码,不要背代码,不要背代码。

 

内容主要分为

1、掌握算法基本思路

2、历年真题

3、课后习题

 

如果发现代码有错误或者有疑问请及时联系我。

放在博客上,主要是因为比较容易修改。

 

不用光顾着看,大脑非常容易欺骗自己,大家必须动手实践一下。

道理就好比记单词。

 

建议:

通过热身环节后,大家自己试着写一下后面的题目。

如果遇到不会才看参考代码,千万不要先入为主直接背代码,这样效率低而且容易忘。

 

热身环节 

子集树问题

代码链接:https://pasteme.cn/25521

 

 1 //子集树
 2  3 #include<queue>
 4 #include<cstdio>
 5 using namespace std;
 6  7 //定义结点记录信息
 8 typedef struct Node{
 9     char path[6];
10     int step ;
11 }Node;
12 13 // BFS套路
14 void BFS(){
15 16     //第一步:定义根节点和队列,并把根节点压入队列
17     queue<Node> Q ;
18     Node first ;
19     first.step = 0 ;
20     Q.push(first) ;
21 22     //第二步:保持队列非空
23     while( !Q.empty() ){
24 25         //第三步:取出队首元素,别忘了同时要弹出队首元素
26         Node cur = Q.front() ;
27         Q.pop() ;
28 29         //第四步:设计 最终状态 进行的操作
30         if( cur.step == 3 ){
31             for( int i = 1 ; i <= 3 ; i ++ ){
32                 printf("%c",cur.path[i]);
33             }
34             putchar('\n');
35             continue ;
36         }
37 38         //第五步:设计 下一步怎么走,用"Next"来命名下一步结点,压入队尾
39 40         Node Next = cur ;
41         Next.step += 1 ;
42 43         //走左边
44         Next.path[ cur.step + 1 ] = 'L' ;
45         Q.push( Next );
46 47         //走右边
48         Next.path[ cur.step + 1 ] = 'R' ;
49         Q.push( Next );
50     }
51 }
52 53 int main()
54 {
55     BFS();
56     return 0;
57 }
子集树问题

 


 

历年真题

 

01背包问题

代码链接:https://pasteme.cn/25528

 

 1 //01背包问题
 2  3 #include<queue>
 4 #include<cstdio>
 5 #include<algorithm>
 6 using namespace std;
 7  8 //定义结点记录信息
 9 typedef struct Node{
10     int val , w ;
11     int step ;
12 }Node;
13 14 int weight[3] = { 16 , 15 , 15 };
15 int value[3] = { 45 , 25 , 25 };
16 int V = 30 ;
17 18 // BFS套路
19 void BFS(){
20 21     int n = 3 ;     // 物品个数
22     int ans = 0 ;   // 答案
23 24     //第一步:定义根节点和队列,并把根节点压入队列
25     queue<Node> Q ;
26     Node first ;
27     first.step = first.val = first.w = 0 ;
28     Q.push(first) ;
29 30     //第二步:保持队列非空
31     while( !Q.empty() ){
32 33         //第三步:取出队首元素,别忘了同时要弹出队首元素
34         Node cur = Q.front() , Next ;
35         Q.pop() ;
36 37         //第四步:设计 最终状态 进行的操作 <=> 到达叶子结点.
38         if( cur.step ==  n ){
39             ans = max( ans , cur.val );
40             continue ;
41         }
42 43         //第五步:设计 下一步怎么走,用"Next"来命名下一步结点,压入队尾
44         Next = cur ;
45         Next.step += 1 ;
46 47         //该操作为:物品不放进背包 <=> 子集树往左边走
48         Q.push( Next );
49 50         //该操作为:物品放入背包 <=> 子集树往右边走
51         //前提是:保证物品能放入背包
52         if( Next.w + weight[ cur.step ] <= V ){
53             Next.w += weight[ cur.step ];
54             Next.val += value[ cur.step ];
55             Q.push( Next ) ;
56         }
57     }
58     printf("%d\n",ans);
59 }
60 61 int main()
62 {
63     BFS();
64     return 0;
65 }
01背包问题

 

布线问题

      

代码链接:https://pasteme.cn/25532

 

  1 //布线问题
  2   3 #include<queue>
  4 #include<cstdio>
  5 #include<algorithm>
  6 using namespace std;
  7   8 //定义结点记录信息
  9 typedef struct Node{
 10     int x , y ;
 11     int step ;
 12 }Node;
 13  14 int dir[4][2] = {
 15         {-1,0},
 16     {0,-1} , {0,1},
 17         {1,0}
 18 };
 19  20 int maze[9][9] ;
 21 int vis[9][9] ;
 22 int n = 9 , m = 9 ;
 23 int Sx,Sy , Ex,Ey ; //Start( x , y ) , End( x ,y )
 24  25 void Init(){
 26     maze[1][3] = maze[2][3] = maze[2][4] =
 27     maze[3][5] = maze[4][4] = maze[4][5] =
 28     maze[5][5] = maze[6][1] = maze[7][1] =
 29     maze[7][2] = maze[7][3] = maze[8][1] =
 30     maze[8][2] = maze[8][3] = 1;
 31  32     vis[1][3] = vis[2][3] = vis[2][4] =
 33     vis[3][5] = vis[4][4] = vis[4][5] =
 34     vis[5][5] = vis[6][1] = vis[7][1] =
 35     vis[7][2] = vis[7][3] = vis[8][1] =
 36     vis[8][2] = vis[8][3] = -1;
 37     Sx = 3 , Sy = 2 ;
 38     Ex = 4 , Ey = 7 ;
 39  40     //起点特定标记
 41     vis[Sx][Sy] = -1 ;
 42 }
 43  44 // BFS套路
 45 void BFS(){
 46  47     //是否能到达终点 的标记位
 48     bool flag = false ;
 49  50     //第一步:定义根节点和队列,并把根节点压入队列
 51     queue<Node> Q ;
 52     Node first = Node{ Sx , Sy , 0 } ;
 53     Q.push(first) ;
 54  55     //第二步:保持队列非空
 56     while( !Q.empty() ){
 57  58         //第三步:取出队首元素,别忘了同时要弹出队首元素
 59         Node cur = Q.front() , Next ;
 60         Q.pop() ;
 61  62         //第四步:设计 最终状态 进行的操作
 63         if( cur.x ==  Ex && cur.y == Ey ){
 64             printf("The Shortest Path : %d\n",cur.step ) ;
 65             flag = true ;
 66             break ;
 67         }
 68  69         //第五步:设计 下一步怎么走,用"Next"来命名下一步结点,压入队尾
 70  71         for( int i = 0 ; i < 4 ; i++ ){
 72             int tx = cur.x + dir[i][0] ;
 73             int ty = cur.y + dir[i][1] ;
 74             if( ( 1 <= tx && tx <= n && 1 <= ty && ty <= m ) && maze[tx][ty] == 0 ){
 75                 if( vis[tx][ty] == 0 ){
 76                     vis[tx][ty] = cur.step + 1  ;
 77                     Next = Node{ tx , ty , cur.step + 1 } ;
 78                     Q.push( Next );
 79                 }
 80             }
 81         }
 82     }
 83     // 如果没有到达终点输出"Impossible"
 84     if( !flag ){
 85         printf("Impossible\n");
 86     }
 87     // 输出BFS遍历路径
 88     else{
 89         for( int i = 1 ; i <= n; i ++ ){
 90             for( int j = 1 ; j <= m ; j++ ){
 91                 printf("%4d",vis[i][j]);
 92             }
 93             putchar('\n');
 94         }
 95         putchar('\n');
 96     }
 97 }
 98  99 int main()
100 {
101     Init();
102     BFS();
103     return 0;
104 }
布线问题

 

课后习题

整数变换问题

代码链接:https://pasteme.cn/25533

关于整数i的变换f和g定义如下:f(i)=3i,g(i)=i/2
试设计一个算法,对于给定的2个整数n和m,用最少的变换次数将n变成m。
输入:
15 4 输出: 4 ggfg
 1 //整数变换问题
 2 //关于整数i的变换f和g定义如下:f(i)=3*i,g(i)= i/2.
 3 //试设计一个算法,对于给定的2个整数n和m,用最少的变换次数将n变成m。
 4  5 #include<queue>
 6 #include<cstdio>
 7 #include<algorithm>
 8 using namespace std;
 9 10 //定义结点记录信息
11 typedef struct Node{
12     int x , step ;
13     char path[30];
14 }Node;
15 16 int S = 15 , E = 4 ;
17 void BFS( int S ){ // Start
18 19     queue<Node> Q;
20     Node first ;
21     first.x = S ;
22     first.step = 0 ;
23     Q.push(first) ;
24 25     while( !Q.empty() ){
26         Node cur = Q.front() , Next ;
27         Q.pop() ;
28 29         if( cur.x == E ){
30             printf("最少变换的次数: %d\n",cur.step );
31 32             //输出变化的过程
33             for( int i = 0 ; i < cur.step ; i ++ )
34                 printf("%c",cur.path[i]);
35             putchar('\n');
36             break ;
37         }
38 39         Next = cur ;
40         Next.x = cur.x * 3 ;
41         Next.step += 1 ;
42         Next.path[cur.step] = 'f' ;
43         Q.push( Next );
44 45         Next = cur ;
46         Next.x = cur.x / 2 ;
47         Next.step += 1 ;
48         Next.path[cur.step] = 'g' ;
49         Q.push( Next );
50     }
51 }
52 53 int main()
54 {
55     BFS(S);
56     return 0;
57 }
58  
整数变换问题

猜你喜欢

转载自www.cnblogs.com/Osea/p/12106718.html