Codeforces Round #529 (Div. 3) D. Circular Dance
阿新 • • 發佈:2018-12-30
題意:
有 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){} 13View Code}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 }
根據大神程式碼改編的簡介程式碼%%%%%
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 }改編自大神程式碼