1. 程式人生 > >今日刷題集合

今日刷題集合

clas 下一個 sum 程序 sca esp 刷題 min targe

月考沒考,最皮的是刷題效率低的可怕,搜索中的那些回溯用的還是很水,不如總結一下。

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天復賽。

那是我願意付諸一生的人,現在卻沒法擁有。

今日刷題集合