zoj 2704 Brackets

费了一中午时间。。。两三个小时。。。或者更长,因为刚开始没有专心在做。

 

因为要练习用栈,所以找到了这题。思路本来有点麻烦了,看了别人写的思路,很神奇,呵呵。我原来只是想着把字符保存到栈里,但是好像输出会很麻烦,看到一种思路就是把序号保存到栈里,然后到最后处理下,不连续的序号就是匹配的,然后比较长短啦~好几种情况需要罗列,最长在首部,最长在中部,最长在尾部,整个串都符合。就这四种情况了。WA了两次就是因为没考虑全这四种情况。

 

AC这题感觉好好~~~~~~哈哈~~~~如果不是用栈我可能会更快滴做出来。。。啧啧。。。额。。忘加注释了,等我加了再贴。。

 

#include <stdio.h> #include <stdlib.h> #include <string.h> int n; int sta[100005];//栈数组 char str[100005]; int stack(int x)//入栈 { sta[n++] = x; } int pop()//出栈 { int x; x = sta[n]; sta[n] = -1; n--; return x; } int match(int m,int n)//检查是否匹配 { if(str[ sta[m] ] == '[' && str[ n ] ==']') return 1; if(str[ sta[m] ] =='(' && str[ n ] == ')') return 1; return 0; } int main(void) { int count = 0,i,len,cha=0,pos; char ch; while(scanf("%s",str) != EOF) { n = 0; memset(sta,'/0',sizeof(sta)); count = 0; //记录匹配的字符的个数 len = strlen(str); stack(0); for(i=1;i<len;i++) { stack(i); if(n<2) //n<2是栈为空 continue; if( match(n-2,i) ) { pop(); pop(); //如果匹配,则刚入的那个数字和原来栈中的那个数字出栈 count+=2; //匹配的话都是成双滴 } } if(count==0) //没有匹配的,输出俩换行 { printf("/n/n"); continue; } if( count == len ) //整个字符串都匹配 { puts(str); printf("/n"); continue; } pos = 0; //这两行是应对如果最长子列在首部 cha = sta[0] -1; for(i=1;i<len-count;i++) //查找最长子列 { if(sta[i] - sta[i-1] -1> cha) { cha = sta[i] - sta[i-1]; pos = i; } } if(len - sta[len-count-1] >cha) //判断最长子列是否在尾部 { for(i=sta[len-count-1]+1;i<len;i++) printf("%c",str[i]); printf("/n/n"); continue; } if(pos==0) //如果pos为0,则最长在首部 { for(i=0;i<sta[0];i++) printf("%c",str[i]); printf("/n/n"); continue; } for(i=sta[pos-1] +1;i<sta[pos];i++) //如果前面都不满足,那么满足要求的肯定在中间了 printf("%c",str[i]); printf("/n/n"); } system("pause"); return 0; }

 

 

PS:写报告的感觉就是比等结果出来的感觉好啊~~~~~~(*^__^*) 嘻嘻……

 

 

 

你可能感兴趣的:(zoj 2704 Brackets)