1. 程式人生 > 其它 >robocom第二次集訓題解(2021.10.8號)

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 }

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