Codeforces Round #288 (Div. 2) E. Arthur and Brackets

题目链接:http://codeforces.com/contest/508/problem/E

  输入一个n,表示有这么多对括号,然后有n行,每行输入一个区间,第i行的区间表示从前往后第i对括号的左括号跟右括号之间的距离在这个区间的范围内,问是否存在这样的括号序列.

我的做法是比较繁琐,稍微看了下别人的代码,比我的短,应该有更简单 的做法.我的做法是从后往前构造括号序列,每次添加一对括号之前,先把当前的括号序列扫一遍,例如这个括号序列:(())()((()))   ,很显然,现在我要新增一对括号上去的话,距离只能是:1,5,7,13,我扫一遍的目的就是扫出这些可能距离,然后判断这些可能的距离中的最小的而且满足在区间里面的距离,然后按照这个距离插入一对新的括号.为什么要最小的呢?因为虽然当前这些距离都是可行的,但是右括号插入的位置越靠后,产生的可行的距离的数目也就变少了,所以要靠前插入,给后面的插入制造更多的机会.

  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 }    
View Code

 

posted @ 2015-03-05 13:31  xiaxiaosheng  阅读(234)  评论(0编辑  收藏  举报