題目:點此,
我處理這種多組資料的方法被我叫做“mains法”,就是先假設只有一組資料,寫一個代碼,然后把那個main函式改成mains,最后寫一個真正的main函式,
這個“真正的”main函式一般有兩種 1.告訴你資料組數:
1 int main(){ 2 int t; 3 cin >> t; 4 for(int i=0;i<t;i++){ 5 mains(); 6 } 7 return 0; 8 }
2.不告訴你資料組數:
1 int main(){ 2 int *|*;//*|*表示根據實際情況會發生變化,這里*|*表示mains中第一個讀入的資料,放在main函式里讀入 3 while(cin >> *|*){ 4 mains(*|*);//*|*用引數的形式告訴mains 5 } 6 }
好了,進入正題
這道題我的思路是:先讀入資料,建立一棵類似于鄰接表存盤的樹(這樣方便調 試,而且貌似也沒有壞處),然后判斷n%k是否等于0,不等直接NO,return 0! 等于繼續,進行深搜,首先找到下一個訪問的頂點進行訪問,然后判斷回傳值(那個結點是該分組的第幾個節點) 是否大于k或=-1(=-1說明已經無法劃分),回傳-1,否則判斷是否等于k,若等于說明已有一組,無需繼續配對 否則將ans變數加上這個回傳值,該節點訪問完畢后return ans,ans初始值為1,不為0, 最后如果根節點回傳值不為k,輸出Yes,否則NO,
(為什么是不等于?我不知道,不等于就AC,等于就爆零) 代碼:
1 #include <cstdio> 2 #include <vector> 3 using namespace std; 4 bool color[100000]={true}; 5 vector <int> tree[100000]; 6 int k; 7 int dfs(int now){ 8 color[now]=false; 9 int number=1; 10 for(int i=0;i<tree[now].size();i++){ 11 if(color[tree[now][i]]){ 12 int a=dfs(tree[now][i]); 13 if(a>k||a==-1){ 14 return -1; 15 } 16 if(a==k){ 17 continue; 18 } 19 number+=a; 20 } 21 } 22 return number; 23 } 24 int mains(){ 25 int n; 26 scanf("%d %d",&n,&k); 27 for(int i=0;i<n;i++){ 28 tree[i].clear(); 29 color[i]=true; 30 } 31 for(int i=0;i<n-1;i++){ 32 int x,y; 33 scanf("%d %d",&x,&y); 34 x--; 35 y--; 36 tree[x].push_back(y); 37 tree[y].push_back(x); 38 } 39 if(n%k!=0){ 40 puts("NO"); 41 return 0; 42 } 43 if(dfs(1)==k){ 44 puts("YES"); 45 } 46 else{ 47 puts("NO"); 48 } 49 return 0; 50 } 51 int main(){ 52 int t; 53 scanf("%d",&t); 54 for(int i=0;i<t;i++){ 55 mains(); 56 //puts("\n"); 57 } 58 return 0; 59 }代碼
補充:
在你已熟練printf和scanf的時候,不要用cin、cout,用printf、scanf,不然cin資料一大,光讀資料就會 TLE,還有如果你會且熟練getchar()或cin.get()讀入整數的話,就用它,應為有些時候資料很大,scanf也 會TLE,所以就要用到它,
附錄:
用getchar或cin.get()讀入資料的基本模板:
1 int read()//視需要可變成long long,unsighed long long…… 2 { 3 int s=0,w=1;//回傳值型別變了,s也要變,w不用變 4 char ch=getchar(); 5 while(ch<'0'||ch>'9') 6 { 7 if(ch=='-') 8 w=-1; 9 ch=getchar(); 10 } 11 while(ch>='0'&&ch<='9') 12 s=s*10+ch-'0',ch=getchar(); 13 return s*w; 14 }
(這次調整了一下順序,犯的錯誤和識訓在后面)
犯的錯誤:
1.dfs如果不滿足條件應該return不是exit,因為如果是單測驗資料,這樣做是可以的,可是它有多組資料,這樣做會直接結束程式,導致后面的測驗資料沒法輸出答案,
2.tree鄰接表沒進行初始化(clear),
3.用vector實作的鄰接表不用頭節點,
4.exit改成return后輸出NO的陳述句沒去掉,
5.判斷是否整除的陳述句應該放在讀資料的后面,不然資料就沒讀完,后面的資料會被認為是下一組資料的開始,
6.color陣列沒初始化,
7.第十行是tree[now]不是tree[i],
識訓:
1.盡量不用exit,除非不是在做題(別忘了我還在開發游戲)
2.遇到多測驗資料的題目,在mains里,三省代碼:變數初始化了嗎??陣列初始化了嗎??stl容器初始化了嗎??
3.添加頭節點的時候,問自己:需要嗎??若需要,寫dfs時,再問一遍:回圈時是否訪問了頭節點??
4.該要改全面,
5.任何操作(除了輸入必須操作)都要在讀資料后執行,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/56841.html
標籤:C++
上一篇:C++之模板模式
