UVa-12166 Equilibrium Mobile

被多校虐的不要不要的,不过集训也过去一(大)半了吧。

这道题前几天写了一下,感觉好麻烦就暂时没写了。今天又拿起来看一下,除了写错一个变量名导致WA了一发外,算是1Y吧,还是感觉很爽的。

下面是我的代码。

后来又看了别人的题解,有的是暴力枚举每一个点做的,比我的要好理解,不过我的时间复杂度肯定要低。还有一个比较牛的方法,见http://blog.csdn.net/kun768/article/details/43208669(实质就是把我的代码中判断是否可以匹配用一个映射保存下来,之后再处理)。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 using namespace std;
 6 const int maxn=1e6;
 7 char s[maxn];
 8 int len,ans;
 9 int find(int a)//找到下一个“,”所在位置
10 {
11     int t=0;
12     for(int i=a;i<len;i++)
13     {
14         if(s[i]=='[') t++;
15         else if(s[i]==']') t--;
16         else if(s[i]==','&&t==0) return i;
17     }
18 }
19 bool isnum(int a)
20 {
21     return s[a]>='0'&&s[a]<='9';
22 }
23 int dfs(int a,int b,int &mx,int &mn)//mx,mn为最大最小值
24 {
25     if(isnum(a))
26     {
27         int m=0;
28         for(int i=a;i<=b;i++) m=m*10+s[i]-'0';
29         mx=mn=m;
30         return m;
31     }
32     else if(s[a]=='[')//继续递归
33     {
34         int p=find(a+1);
35         int mx1,mn1,mx2,mn2;
36         int l=dfs(a+1,p-1,mx1,mn1);//左子树
37         int r=dfs(p+1,b-1,mx2,mn2);//右子树
38         if(mx1!=mx2&&mx1!=mn2&&mn1!=mx2&&mn1!=mn2) ans++;//不管怎么改都无法匹配
39         mx=2*max(l,r),mn=2*min(l,r);
40         return mn;//返回小值
41     }
42 }
43 int main()
44 {
45     //freopen("in.txt","r",stdin);
46     //freopen("out.txt","w",stdout);
47     int T;
48     scanf("%d",&T);
49     while(T--)
50     {
51         scanf("%s",s);
52         len=strlen(s);
53         ans=0;
54         int mx,mn;
55         dfs(0,len-1,mx,mn);
56         printf("%d
",ans);
57     }
58 }
原文地址:https://www.cnblogs.com/windrises/p/4711835.html