-
题目OJ地址:
http://cdqz.openjudge.cn/noip/1002/
题目描述:
时间限制:
- 50000ms 内存限制:
- 2560000kB
-
描述
有n个人参加一个舞蹈课。每个人的舞蹈技术由整数来决定。在舞蹈课的开始,他们从左到右站成一排。当这一排中至少有一对相邻的异性时,舞蹈技术相差最小的那一对会出列并开始跳舞。如果不止一对,那么最左边的那一对出列。一对异性出列之后,队伍中的空白按原顺序补上(即:若队伍为ABCD,那么BC出列之后队伍变为AD)。舞蹈技术相差最小即是a
i的绝对值最小。
你的任务是,模拟以上过程,确定跳舞的配对及顺序。
-
View Code
1 #include<cstdio> 2 #include<cstdlib> 3 #include<algorithm> 4 #include<iostream> 5 #include<vector> 6 7 using namespace std; 8 9 struct node 10 { 11 char sex;int val,l,r,exi; 12 }pdf[200001]; 13 14 struct sb 15 { 16 int l,r,val; 17 }ergo[200001],solu[200001]; 18 19 char sex[200001];int p=0,n; 20 21 bool cmp(sb a,sb b) 22 { 23 if(a.val==b.val) return a.l>b.l; 24 else return a.val>b.val; 25 } 26 27 inline void del(int i) 28 { 29 if(pdf[i].l>=0) pdf[pdf[i].l].r=pdf[i].r; 30 if(pdf[i].r<=n-1) pdf[pdf[i].r].l=pdf[i].l; 31 pdf[i].exi=0; 32 } 33 34 int main() 35 { 36 freopen("DancingLessons.in","r",stdin); 37 freopen("DancingLessons.out","w",stdout); 38 39 scanf("%d",&n); 40 scanf("%s",sex); 41 for(int i=0;i<n;i++) pdf[i].sex=sex[i]; 42 43 for(int i=0;i<n;i++) 44 { 45 int tmp; 46 scanf("%d",&tmp); 47 pdf[i].l=i-1; 48 pdf[i].r=i+1; 49 pdf[i].exi=1; 50 pdf[i].val=tmp; 51 52 if(i!=0&&pdf[i].sex!=pdf[i-1].sex) 53 { 54 ergo[++p].val=abs(pdf[i].val-pdf[i-1].val); 55 ergo[p].l=i-1,ergo[p].r=i; 56 } 57 } 58 make_heap(&ergo[1],&ergo[p+1],cmp); 59 60 int sol=0; 61 while(p>=1) 62 { 63 sb k=ergo[1],k2; 64 while((!(pdf[k.l].exi&&pdf[k.r].exi))&&p>=1) pop_heap(&ergo[1],&ergo[p+1],cmp),p--,k=ergo[1]; 65 if(p==0) break; 66 67 solu[++sol]=k; 68 if(pdf[k.l].l>=0&&pdf[k.r].r<=n-1) 69 if(pdf[pdf[k.l].l].sex!=pdf[pdf[k.r].r].sex) 70 { 71 k2.l=pdf[k.l].l;k2.r=pdf[k.r].r; 72 k2.val=abs(pdf[pdf[k.l].l].val-pdf[pdf[k.r].r].val); 73 74 ergo[p+1]=k2; 75 push_heap(&ergo[1],&ergo[p+2],cmp);p++; 76 } 77 78 del(k.l);del(k.r); 79 } 80 81 printf("%d\n",sol); 82 for(int i=1;i<=sol;i++) 83 printf("%d %d\n",solu[i].l+1,solu[i].r+1); 84 85 return 0; 86 }