首页 > 代码库 > 今日刷题集合

今日刷题集合

月考没考,最皮的是刷题效率低的可怕,搜索中的那些回溯用的还是很水,不如总结一下。

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天复赛。

 

 

 

 

 

 

 

 

 

 

那是我愿意付诸一生的人,现在却没法拥有。

今日刷题集合