UVa 11111 一般Matrioshka 及 scanf 处理一行
题目:nest,嵌套
思路:思路想通了其实很简单:将负数压栈,遇到输入正数时,检查栈顶元素,如果栈顶是正数,则出栈,一直检查栈顶元素直到栈顶是负数,判断该数和栈顶负数是否为相反数,并判断出栈的那些正数之和是否小于该输入的正数(这个是满足题目中的相加小于m的条件)。如果满足,则栈顶负数出栈,输入的正数入栈。这样循环到最后,如果一直匹配则最后栈中只剩一个元素。 思路很清晰,但实现起来比较麻烦,主要是EOF和\n的判断。我一直以为scanf是不能用来辨别一行的,因为它会跳过空白符。看了别人的一篇,才发觉scanf和getchar搭配还是可以处理一行的,因为scanf每次读过之后是停留在不匹配字符或空白字符处的,所以scanf后用getchar就可以判断是读到了一行行尾还是EOF还是正常地方。这里我是把每行划分为一个char+int组(int是在char判断不为换行时才进行读入),这样当char为换行时循环条件失败不再读入数字,而该行最后一个数字在上一次循环中已处理。但是这样会导致第一个int前没有char,这里是单独处理,情形也比较简单;如果是用int+char组来划分(即在while循环尾部先读int再读char),这样会导致换行的时候,最后一个int没有处理,需要在while循环外用相同的语句进行处理,比较麻烦。(这里的思想就是先判断再处理,即尽量不在循环最后处进行输入)这里根据AC的程序来看,应该是每行都有换行,不会最后一行只有EOF没有换行。
吐槽的是,开始的时候以为整数是一位数,就写了一个函数用getchar()然后返回int,发现不能处理多位数之后就按这个进行改,越改越麻烦。。到最后还RE。。。发现这样又是判断EOF里面又判断\n的用getchar就很麻烦需要很细心。。也许像这个程序一样,把每行先保存下来再处理比较好。。。
小结:scanf后跟getchar是可以辨别一行的。
Code:
//AC
#include<stdio.h> #include<string.h> int stack[10000]; int main() { int num; while(scanf("%d",&num)!=EOF) { char c=getchar(); int flag=1; memset(stack,0,sizeof(stack)); int top=0; if(num<0) stack[++top]=num; else {flag=0;}; while(c!=‘\n‘) { scanf("%d",&num); if(num<0) stack[++top]=num; else { int sum=0; while(top>0 && stack[top]>0) { sum+=stack[top--]; } if(num+stack[top]==0&&sum<num) stack[top]=num; else flag=0; } if(flag==0) while((c=getchar())!=‘\n‘); else c=getchar(); }//whilec if(flag&&top==1) printf(":-) Matrioshka!\n"); else printf(":-( Try again.\n"); } return 0; }
//RE #include<stdio.h> #include<string.h> #include<ctype.h> #include<stdlib.h> int stack[10000]; int getin(int* flag); int main() { int a; int* fg; int next1=1; while((a=getin(fg))&& next1) {//*fg==2是EOF int next2=1; if(*fg==2) next1=0; else if(*fg==1) next2=0; memset(stack,0,sizeof(stack)); int top=0; int flag=1; while(next2) {//*fg==1是换行 if(*fg==1) next2=0; else if(*fg==2) {next1=0; break;} if(a<0) stack[++top]=a; else {//a>0 int sum=0; while(top>0 && stack[top]>0) sum+=stack[top--]; if(top>0 &&stack[top]+a==0 && sum<a) { stack[top]=a; } else { flag=0;}//这里不需要break } if(flag==0 && next2) { while((a=getin(fg))&& *fg==0); break;} else if(next2!=0) a=getin(fg); }//while if(flag==0||top!=1) printf(":-( Try again.\n"); else printf(":-) Matrioshka!\n"); }//while return 0; } int getin(int* flag) {//读入一个正数或负数,标记flag为1表示读到一行,为2表示读到EOF char str[9]; int k=0; char c=getchar(); while(isdigit(c)||c==‘-‘) { str[k++]=c; c=getchar(); } str[k]=‘\0‘; *flag=0; if(c==‘\n‘) *flag=1; else if(c==EOF) *flag=2; return atoi(str); }