Codeforces Round #288 (Div. 2) E. Arthur and Brackets
题目链接:http://codeforces.com/contest/508/problem/E
输入一个n,表示有这么多对括号,然后有n行,每行输入一个区间,第i行的区间表示从前往后第i对括号的左括号跟右括号之间的距离在这个区间的范围内,问是否存在这样的括号序列.
我的做法是比较繁琐,稍微看了下别人的代码,比我的短,应该有更简单 的做法.我的做法是从后往前构造括号序列,每次添加一对括号之前,先把当前的括号序列扫一遍,例如这个括号序列:(())()((())) ,很显然,现在我要新增一对括号上去的话,距离只能是:1,5,7,13,我扫一遍的目的就是扫出这些可能距离,然后判断这些可能的距离中的最小的而且满足在区间里面的距离,然后按照这个距离插入一对新的括号.为什么要最小的呢?因为虽然当前这些距离都是可行的,但是右括号插入的位置越靠后,产生的可行的距离的数目也就变少了,所以要靠前插入,给后面的插入制造更多的机会.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<vector> 6 #include<deque> 7 using namespace std; 8 typedef struct node 9 { 10 int flag; 11 node *next; 12 }Linklist; 13 int n,inter[610][2],temp[2000]; 14 int reader(Linklist* head,int* temp) 15 { 16 int flag = 0,t = 0,f = 0; 17 Linklist *p = head->next; 18 while(p != NULL) 19 { 20 if(flag == 0) 21 { 22 temp[f++] = t; 23 t = 0; 24 } 25 t++; 26 flag += p->flag; 27 p = p->next; 28 } 29 if(flag == 0) 30 temp[f++] = t; 31 return f; 32 } 33 void insert(Linklist* head,int tot) 34 { 35 int f = 0; 36 Linklist *q = new Linklist; 37 q->flag = 1; 38 q->next = head->next; 39 head->next = q; 40 Linklist *p = head; 41 while(tot--) 42 p = p->next; 43 Linklist *t = new Linklist; 44 t->flag = -1; 45 t->next = p->next; 46 p->next = t; 47 } 48 void clean(Linklist *p) 49 { 50 if(p->next == NULL) 51 { 52 delete p; 53 return ; 54 } 55 clean(p->next); 56 } 57 void print(Linklist *head) 58 { 59 Linklist *p = head->next; 60 while(p!= NULL) 61 { 62 printf("%d ",p->flag); 63 p = p->next; 64 } 65 puts(""); 66 } 67 int main() 68 { 69 while(scanf("%d",&n)!=EOF) 70 { 71 for(int i = 0;i < n;++i) 72 scanf("%d%d",&inter[i][0],&inter[i][1]); 73 int flag = 0,t = 0; 74 Linklist *head = new Linklist; 75 head->flag = 0; //初始化头节点,头节点不存信息 76 head->next = NULL; 77 int ans = 1; 78 for(int i = n - 1;i >= 0;--i) 79 { 80 int num = reader(head,temp); //返回的是temp中数值的个数 81 int ff = 0,tot = 1; 82 for(int j = 0;j < num;++j) 83 { 84 tot += temp[j]; 85 if(tot >= inter[i][0] && tot <= inter[i][1]) 86 { 87 insert(head,tot); //执行在0位置插入'('跟在tot位置插入')' 88 ff = 1; //已找到满足的条件,退出 89 break; 90 } 91 } 92 if(ff == 0) 93 { 94 ans = 0; 95 break; 96 } 97 } 98 if(ans) 99 { 100 Linklist *p = head->next; 101 while(p) 102 { 103 printf(p->flag == 1? "(":")"); 104 p = p->next; 105 } 106 puts(""); 107 } 108 else puts("IMPOSSIBLE"); 109 clean(head); //回收内存 110 } 111 return 0; 112 }