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------

上一篇:dig和nslookup的区别与简单应用


下一篇:[日常] DNS解析概述