robocom第二次集训题解(2021.10.8号)
作者:互联网
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 }
0X06 PAT 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 }
0X07 Tree 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 }
0X08 Deepest Root
解:本题大意是给出一个图,判断它是否满足树的条件,如果是则从A节点开始去遍历每个节点如果假设起始节点的深度为0,那么不妨设A节点的深度为n,设还有一个B节点的深度为m,那么如果以A节点为根节点进行造树的话,那么B的深度就是n+m,从此可知:我们可以选最深的点和次深的点作为起始和结束节点进行dfs(不知道为啥有个点一直没过,代码就先不发了)。
------EOF------
标签:10,p1,2021.10,int,题解,dig,maxn,robocom,节点 来源: https://www.cnblogs.com/GIN-DYD/p/15376914.html