今日刷題集合
阿新 • • 發佈:2017-05-11
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 , intk ) 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> 2int 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天復賽。
那是我願意付諸一生的人,現在卻沒法擁有。
今日刷題集合