1. 程式人生 > >Codeforces Round #529 (Div. 3) D. Circular Dance

Codeforces Round #529 (Div. 3) D. Circular Dance

傳送門

 

題意:

  有 n 個孩子編號為 1~n ,繞著聖誕樹 dance;

  編號為 i 的孩子可以記住ai1,ai2兩個小孩,ai1,ai2是 i 在順時針方向的相鄰的兩個小孩,但ai1,ai2不一定是按順時針方向排列的;

  給出每個孩子相鄰兩個孩子的資訊,讓你還原這個序列。

題解:

  可以以任一孩子作為第一個孩子,假設以編號 1 為第一個,編號1有兩個相鄰的孩子資訊 a,b

  如果 b 在 a 的順時針方向,那麼第二個孩子就是 a,反之為 b。

  確定了前兩個孩子後

  i 從 1 開始遍歷,第 i 個孩子的兩個相鄰的孩子a,b已經確定一個在 i+1 位置了,那麼剩下的那個肯定在 i+2 位置,遍歷到 n-2 卻id確定最終序列。

AC程式碼:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 #define mem(a,b) memset(a,b,sizeof(a))
 6 const int maxn=2e5+10;
 7 
 8 int n;
 9 struct Node
10 {
11     int a,b;//i的順時針方向相鄰的兩個孩子
12     Node(int _a=0,int _b=0):a(_a),b(_b){}
13
}nex[maxn]; 14 bool vis[maxn]; 15 int q[maxn]; 16 17 void Solve() 18 { 19 mem(vis,false); 20 21 q[1]=1; 22 int x=nex[1].a,y=nex[1].b; 23 q[2]=(nex[x].a == y || nex[x].b == y ? x:y);//確定第二個位置的孩子的編號 24 vis[q[1]]=true,vis[q[2]]=true; 25 for(int i=1;i <= n-2;++i) 26 { 27 x=nex[q[i]].a;
28 y=nex[q[i]].b; 29 q[i+2]=(!vis[x] ? x:y); 30 vis[q[i+2]]=true; 31 } 32 for(int i=1;i <= n;++i) 33 printf("%d ",q[i]); 34 } 35 int main() 36 { 37 scanf("%d",&n); 38 for(int i=1;i <= n;++i) 39 { 40 int a,b; 41 scanf("%d%d",&a,&b); 42 nex[i]=Node(a,b); 43 } 44 Solve(); 45 return 0; 46 }
View Code

根據大神程式碼改編的簡介程式碼%%%%%

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 const int maxn=2e5+10;
 5 
 6 int n;
 7 int a[maxn];
 8 int b[maxn];
 9 bool vis[maxn];
10 
11 int Find(int nex1,int nex2)
12 {
13     return !vis[nex1] && (a[nex1] == nex2 || b[nex1] == nex2) ? 0:1;
14 }
15 void Solve()
16 {
17     int x=1;
18     for(int i=1;i <= n;++i)
19     {
20         printf("%d ",x);
21         vis[x]=true;
22         int nex[2]={a[x],b[x]};
23         x=nex[Find(nex[0],nex[1])];
24     }
25 }
26 int main()
27 {
28     scanf("%d",&n);
29     for(int i=1;i <= n;++i)
30         scanf("%d%d",a+i,b+i);
31     Solve();
32     return 0;
33 }
改編自大神程式碼