月考没考,最皮的是刷题效率低的可怕,搜索中的那些回溯用的还是很水,不如总结一下。
codevs 题号:1501 1506 1842 1983 2549 2806 3143 3145 1008 1294 1295
1501 二叉树的最大宽度和高度(没加using namespace std ;会过不去编译,max、min函数封装在#include<iostream>里,所以没有using namespace std ;不行。)
1 #include<bits/stdc++.h> 2 int q[20][3] , w , h , s[20]; 3 void dfs(int n , int k ) 4 { 5 s[k] ++ ;//该层宽度 6 h = max(h,k);//高度 7 if(a[n][0]) dfs(a[n][0],k+1);//如果左儿子存在,向左搜 8 if(a[n][1]) dfs(a[n][1],k+1);//右儿子存在,向右搜。 9 return ; 10 } 11 int main () 12 { 13 int a; 14 scanf("%d",&a); 15 for(int i = 1 ; i< = a ; i ++) 16 scanf("%d%d",&q[i][0],&q[i][1]);//存入这棵树 17 dfs(1,1);//从头(1,1)搜 18 for(int i = 1 ; i <= 19 ; i ++) 19 w = max(w,s[i]);//找出最大宽度 20 printf("%d%d",w,h);//输出最大宽度和高度 21 return 0 ; 22 }
1506 传话(其实这倒是一道图论题,用flody做的dp题,但是不知道为什么codevs上写的是搜索,事实上搜索可做。但是很麻烦(dalao、神牛、神犇请自动忽略这句话))
1 #include<bits/stdc++.h> 2 int n , m , flag; 3 bool f[1001][1001] , q[1001][1001]; 4 void dfs(int x , int y) 5 { 6 if(flag) return ;//如果可以传回来直接return。 7 if(f[x][y]){//如果可以往下一步走,就把flag制为1。 8 flag = 1 ; 9 return ; 10 } 11 for(int i =1 ; i <= n ; i ++) 12 if(f[x][i] && !q[x][i]){//判断这个点往下能不能走,走没走过 13 q[x][i] = 1;//走过了制为1,防止重复地走。 14 dfs(i ,y);//这个i是下一个点的数 15 } 16 return ; 17 } 18 int main() 19 { 20 scanf("%d%d",&n,&m); 21 int a , b ; 22 for(int i = 1 ; i <= m ; i ++){ 23 scanf("%d%d",&a,&b); 24 f[a][b] = 1 ; //类似图论的邻接矩阵中,两个认识就把两点之间制为1。 25 } 26 for(int i = 1 ; i <= n ; i ++){ 27 flag = 0 ; 28 memset(q,0,sizeof(q)); 29 dfs(i,i);//一共有几次就搜索几次 30 if(flag) printf("T\n"); 31 if(!flag) printf("F\n"); //一定要加\n不然真的花式翻车。 32 } 33 return 0 ; 34 }
1842 递归第一次(有一点像搜索,算是子程序递归吧(似乎搜索就是这个)看着玩玩)
1 #include<cstdio> 2 #include<cmath> 3 #include<iostream> 4 using namespace std ; 5 int F(int n) 6 { 7 if(n>=0) 8 return 5 ; 9 else if (n<0) 10 { 11 return F(n+1)+F(n+2)+1; 12 } 13 } 14 int main() 15 { 16 int n; 17 cin>>n; 18 printf("%d\n",F(n)); 19 return 0; 20 }
1983 等式问题
1 #include<bits/stdc++.h> 2 long long a ,ans ; 3 void dfs(int sum , int step){ 4 if(step == 10){ 5 if(sum == a) ans ++;//处理算出来的数据,然后回溯 6 return ; 7 } 8 for(int i = step ;i <= 9 ; i ++) 9 { 10 int t = 0 ; 11 for(int j =step ; j <= i ; j ++) 12 t = t * 10 + j ;//中间不加符号 13 dfs(sum + t , i + 1);//搜索下一步 14 if(step>1) dfs(sum-t,i-1);//回溯 15 } 16 } 17 int main() 18 { 19 int a; 20 scanf("%lld",&a); 21 dfs(0,1);//目前和为0,是第一步。 22 printf("%lld",ans); 23 return 0 ; 24 }
2549 自然数和分解
1 #include<bits/stdc++.h> 2 int a , ans ; 3 void dfs(int x, int num) 4 { 5 if(x == 0) {ans ++ ; return ;}//这个题是反向思维逻辑,所以x能被剪到0也就可以证明自然数和已经分解了 6 for(int i = num ; i <= a ; i ++) 7 if(x-i>=0) dfs(x-i,i);//如果还能作差的话,往下搜。 8 } 9 int main () 10 { 11 scanf("%d",&a); 12 dfs(a,1);//进入子程序的是这个数和第一个作差的数1. 13 printf("%d",ans); 14 return 0 ; 15 } 16
拖更2806 3143 3145 1008 1294 1295
还有155天初赛, 还有183天复赛。
那是我愿意付诸一生的人,现在却没法拥有。
时间: 2024-10-14 00:59:00