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\n",ans); 57 } 58 }