题目: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);
}