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);
}

UVa 11111 一般Matrioshka 及 scanf 处理一行,布布扣,bubuko.com

时间: 2024-12-24 13:21:52

UVa 11111 一般Matrioshka 及 scanf 处理一行的相关文章

uva 11111 - Generalized Matrioshkas

  Problem B - Generalized Matrioshkas  Vladimir worked for years making matrioshkas, those nesting dolls that certainly represent truly Russian craft. A matrioshka is a doll that may be opened in two halves, so that one finds another doll inside. The

Generalized Matrioshkas UVA 11111

说说: 题意就是一个大整数中包含几个小整数,且小整数的和要大于大整数.同时小整数中也可能包含其他小整数,依次类推.要求判断整个的包含关系是否正确.只是题目给的说明不是很清楚.首先给你一个序列,比如:-9     -7     -2    2     -3     -1     -2    2    1    3    7    9  其中9的范围就是-9到9之间,并且只包含了7.如果序列为-9 -7 7 -2 2 9 则9中就包含了7和2两个数字,显然这种情况是不合法的.解法的话,无非就是建立两

讀入scanf,%d和%lld問題

在做一道題目時,用不同的格式化字符讀入在不同的OJ上會有不同的結果. poj_2689/ uva_10140 Prime Distance poj題目鏈接:http://poj.org/problem?id=2689 題目: Description The branch of mathematics called number theory is about properties of numbers. One of the areas that has captured the interes

正则与sed,grep,awk三剑客

系统登录顺序: /etc/profile /etc/profile.d/a.sh (a.sh自己建的) /root/.bash_profile /root/.bashrc /etc/bashrc /bin/bash 提供命令解释器(终端) 直接打/bin/bash 非登录shell /root/.bashrc /etc/bashrc /etc/profile.d/a 可将别名alias等写入以上三个文件 正则表达式: grep -n  只显示行号 -o 只显示匹配内容 -q  安静模式,不打印

c语言实现统计单词个个数

编程实现,从键盘上输入一行字符,统计其中单词的个数. 其中:单词以空格分隔,且空格的个数至少一个. 要求:数组类型为字符型 使用scanf输入一行字符. 输出:单词的个数. 重点:一行字符个数最大为80,定义一维数组来存放这些字符, 当遇到空格时继续查看下一个是否非空格字符,若是,则单词个数加1, 否则,继续读字符,直到结束. 注: 最后一步的输出我输出的变量是count++;的是因为在计算个时候我没有计算第一个单词, 因此要把第一个单词加上.所以输出个数的时候就要输出count++; 代码:

大数处理 _______整数乘法_________1042_____________________________

//最恶心人的大数问题...我怕要让你看到我更恶心!!!!!!!!!!!!!!! #include<stdio.h> #include<string.h> int i,j,m,n,b,c,a[11111]; int main() { while(scanf("%d",&n)!=EOF) { memset(a,0,sizeof(a)); m=0; a[0]=1; for(i=1;i<=n;i++) //思想就是用两个for循环 第一个for循环 一个

UVa 442 矩阵链乘及scanf说明符中的\n

题目:计算题给矩阵相乘次序所需的相乘次数.   我们已知的m*n和n*k矩阵相乘,得到的是m*k矩阵,但需要的相乘次数是m*n*k(开始当成了m*k %>_<%).evaluate,求值 思路:每个矩阵用结构体表示,有名字.行.列.需要计算的次数.矩阵相乘的过程用栈来模拟.遇到左括号(,压栈这是自然的.遇到一个矩阵时,检查栈顶,如果栈顶元素是左括号,则压栈,否则就是矩阵,则比较栈顶矩阵和输入矩阵是否匹配,如果匹配则修改栈顶矩阵的列.计算次数,这样输入矩阵对栈顶进行了修改,相当于完成了相乘,这时

[2016-02-09][UVA][699][The Falling Leaves]

时间:2016-02-09 13:29:10 星期二 题目编号:UVA 699 题目大意:  给一棵树,每棵树有一个叶子,叶子的值是点权,求叶子垂直落下后, (同一个方向的形成一堆),求每堆叶子的总权值 位置的描述:每个左子树在根左边一个单位,右子树在根右边一个单位 分析: 遍历一遍二叉树,传参保存每个二叉树的位置,最后保存即可 每行不超过80个字符,那么节点数不大于80个,堆数不大于80个 方法:dfs,递归 解题过程遇到问题: 一行数据不一定就是一颗完整的树!!!!!!! 开始还以为读取到第

uva 260 - Il Gioco dell&#39;X

题解: 一定有人获胜,非黑即白:获胜条件为:black是由 上走到下,white是由 左走到右: 1 #include <cstdio> 2 using namespace std; 3 int N; 4 char board[201][201]; 5 const int direction[][2] = {{-1,-1},{-1,0},{0,-1},{0,1},{1,0},{1,1}}; 6 void DFS(int i, int j, char c,int &win) 7 { 8