robocom第二次集訓題解(2021.10.8號)
阿新 • • 發佈:2021-10-08
robocom比賽即將臨近,本週暫且不開設線下培訓了,希望大家可以在10.9號的比賽中取得好成績,本次題解就按照部落格的形式進行釋出了,就我對本次的題目進行一下我個人程式碼的說明,具體如果有問題的話可以去CSDN上檢視具體細節。
0X01人以群分
解:沒啥好說的主次排序,sort一把梭,注意奇偶情況分類。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn =1e5+10; 4 string str1="Outgoing #: ",str2="Introverted #: ",str3="Diff ="; 5 int n,a[maxn]; 6 int main() 7 { 8 scanf("%d",&n); 9 for(int i=1;i<=n;i++) scanf("%d",&a[i]); 10 sort(a+1,a+n+1); 11 int ans1=0,ans2=0; 12 for(int i=1;i<=(n>>1);i++){ 13 ans1+=a[i]; ans2+=a[n-i+1]; 14 } 15 if(n&1){ 16 int t1=ans1+a[n/2+1],t2=ans2+a[n/2+1]; 17 if(abs(t1-ans2)>abs(t2-ans1)) 18 cout<<str1<<n/2<<endl<<str2<<n/2+1<<endl<<str3<<abs(t1-ans2); 19 else cout<<str1<<n/2+1<<endl<<str2<<n/2<<endl<<str3<<abs(t2-ans1);20 } 21 else cout<<str1<<n/2<<endl<<str2<<n/2<<endl<<str3<<abs(ans2-ans1); 22 return 0; 23 }
0X02 悄悄關注
解:sort加個過載符號一把梭,篩選一波字串,然後排一下序就可以了。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn = 1e4+10; 4 map <string,int> M; 5 struct per{ 6 int dig; 7 string name; 8 bool operator <(const per&x)const{return dig>x.dig;} 9 }a[maxn]; 10 int n,m; 11 string str; 12 set<string> v; 13 set<string>:: iterator it; 14 double ave=0; 15 int main() 16 { 17 scanf("%d",&n); 18 while(n--) {cin>>str; M[str]=1;} 19 scanf("%d",&m); 20 for(int i=1;i<=m;i++) 21 cin>>a[i].name>>a[i].dig; 22 sort(a+1,a+m+1); 23 for(int i=1;i<=m;i++) ave+=a[i].dig; 24 ave/=m; 25 for(int i=1;i<=m;i++) 26 if(a[i].dig>ave&&M[a[i].name]==0) v.insert(a[i].name); 27 else if(a[i].dig<=ave) break; 28 if(!v.size()) printf("Bing Mei You"); 29 else{ 30 for(it=v.begin();it!=v.end();it++) 31 { 32 if(it!=v.begin()) cout<<endl; 33 cout<<*it; 34 } 35 } 36 return 0; 37 }
0X03 圖著色問題
解:dfs,搜尋一下相鄰節點有沒有與當前點顏色相同的點,有就直解報錯(注意統計一下使用顏色的數量)。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn = 550; 4 int V,E,K,n; 5 int a[maxn]; 6 set<int> s; 7 vector<int> v[maxn]; 8 bool judge(int p) 9 { 10 for(int i=0;i<v[p].size();i++) 11 if(a[v[p][i]]==a[p]) return false; 12 return true; 13 } 14 int main() 15 { 16 scanf("%d%d%d",&V,&E,&K); 17 for(int i=1;i<=E;i++) 18 { 19 int t1,t2; scanf("%d%d",&t1,&t2); 20 v[t1].push_back(t2); v[t2].push_back(t1); 21 } 22 scanf("%d",&n); 23 for(int i=1;i<=n;i++) 24 { 25 if(i!=1) printf("\n"); 26 memset(a,0,sizeof(a)); 27 s.clear(); bool f=true; 28 for(int i=1;i<=V;i++) scanf("%d",&a[i]),s.insert(a[i]); 29 for(int i=1;i<=V;i++) 30 if(!judge(i)) {f=false; break;} 31 if(s.size()!=K||!f) printf("No"); 32 else printf("Yes"); 33 } 34 return 0; 35 }
0X04 深入虎穴
解:本題先統計一下入度,把入度為0的點作為樹的根節點然後遍歷一遍統計一下深度就可以了。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn = 1e5+10; 4 vector<int> v[maxn]; 5 int n,a[maxn],root; 6 int ans=0,deep=0; 7 void dfs(int p,int dep) 8 { 9 if(dep>deep&&v[p].size()==0){ 10 deep=dep; ans=p; 11 return; 12 } 13 if(!v[p].size()) return; 14 for(int i=0;i<v[p].size();i++) 15 dfs(v[p][i],dep+1); 16 } 17 int main() 18 { 19 memset(a,0,sizeof(a)); 20 scanf("%d",&n); 21 for(int i=1;i<=n;i++) 22 { 23 int m; scanf("%d",&m); 24 for(int j=1;j<=m;j++) 25 { 26 int temp; scanf("%d",&temp); 27 a[temp]=1; v[i].push_back(temp); 28 } 29 } 30 for(int i=1;i<=n;i++) 31 if(!a[i]) root=i; 32 dfs(root,1); 33 printf("%d",ans); 34 return 0; 35 }
0X05 Colors in Mars
解:進位制轉化一下,改成字串注意前補一下0。
1 #include<bits/stdc++.h> 2 using namespace std; 3 int main() 4 { 5 cout<<"#"; 6 for(int i=1;i<=3;i++) 7 { 8 int n; scanf("%d",&n); 9 if(!n) {cout<<"00"; continue;} 10 string tmp=""; 11 while(n) 12 { 13 int temp=n%13; 14 temp<10?temp+=0x30:temp+=55; 15 tmp+=(char)temp; 16 n/=13; 17 } 18 if(tmp.length()==1) tmp=tmp+'0'; 19 for(int j=1;j>=0;j--) cout<<tmp[j]; 20 21 } 22 return 0; 23 }
0X06PAT Ranking
解:模擬題,思路為先對每一組進行一個小排序以確定每組的後兩個答案,然後進行一個總的排序,確定第二個答案,最後總體輸出。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn = 3e4+10; 4 int n,m; 5 int p1=1,p2=1; 6 struct per{ 7 string name; 8 int dig; 9 int locnum,locrank; 10 int rank; 11 }a[maxn]; 12 bool cmp(per x,per y) 13 {return x.dig>y.dig||(x.dig==y.dig&&x.name<y.name);} 14 int main() 15 { 16 scanf("%d",&n); 17 for(int i=1;i<=n;i++) 18 { 19 scanf("%d",&m); 20 p1=p2; p2+=m; 21 for(int j=0;j<m;j++){ 22 cin>>a[j+p1].name>>a[j+p1].dig; 23 a[j+p1].locnum=i; 24 } 25 sort(a+p1,a+p2,cmp); 26 int num=a[p1].dig,tot=1; 27 a[p1].locrank=tot; 28 for(int j=p1+1;j<p2;j++) 29 { 30 ++tot; 31 if(a[j].dig==a[j-1].dig) 32 a[j].locrank=a[j-1].locrank; 33 else a[j].locrank=tot; 34 } 35 } 36 sort(a+1,a+p2,cmp); 37 int num=a[1].dig,tot=1; 38 a[1].rank=1; 39 for(int j=2;j<p2;j++) 40 { 41 ++tot; 42 if(a[j].dig==a[j-1].dig) 43 a[j].rank=a[j-1].rank; 44 else a[j].rank=tot; 45 } 46 cout<<p2-1; 47 for(int i=1;i<p2;i++) 48 cout<<endl<<a[i].name<<" "<<a[i].rank<<" "<<a[i].locnum<<" "<<a[i].locrank; 49 return 0; 50 }
0X07Tree Traversals Again
解:這題細算一下,實際上是一個模擬,大家可以根據畫圖來模擬一下樣例,然後在打程式碼,注意細節的問題就是在模擬棧的時候注意一下對結點的定位,不要出現棧溢位的情況!
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,root,point; 4 bool fir=true; 5 stack<int> s; 6 struct node{ 7 int left,right; 8 }a[35]; 9 void print(int p) 10 { 11 if(a[p].left) print(a[p].left); 12 if(a[p].right) print(a[p].right); 13 fir?fir=false:printf(" "); 14 printf("%d",p); 15 } 16 int main() 17 { 18 scanf("%d",&n); 19 for(int i=1;i<=2*n;i++) 20 { 21 string str; cin>>str; 22 if(i==1){ 23 scanf("%d",&root); s.push(root); 24 point=root; continue; 25 } 26 if(str=="Push") 27 { 28 int temp; scanf("%d",&temp); 29 a[point].left==0?a[point].left=temp:a[point].right=temp; 30 s.push(temp); point=temp; 31 } 32 else point=s.top(),s.pop(); 33 } 34 print(root); 35 return 0; 36 }
0X08Deepest Root
解:本題大意是給出一個圖,判斷它是否滿足樹的條件,如果是則從A節點開始去遍歷每個節點如果假設起始節點的深度為0,那麼不妨設A節點的深度為n,設還有一個B節點的深度為m,那麼如果以A節點為根節點進行造樹的話,那麼B的深度就是n+m,從此可知:我們可以選最深的點和次深的點作為起始和結束節點進行dfs(不知道為啥有個點一直沒過,程式碼就先不發了)。
------EOF------