UVa 699 落叶

题意:题意我都快记不清了!!!被坑好久。。就是从根结点开始,每往左走一步,横坐标减1,往右走一步横坐标加1。然后统计同一横坐标下的data值之和。

思路:这个我特地先想了能不能用递归建树的,后来发现在建树过程中其实就可以算了。用一个数组来存各横坐标的data值,然后每来一个该横坐标的结点就直接加上就可以了,完了再遍历输出。

很简单的,思路也很清晰。本来以为可以一次过的,结果4次TLE+6次WA。。。简直破纪录了!!开始TLE的原因是while死循环,因为我传的flag变量没用指针,一直不能break出循环。(本来还以为算法有问题呢,但觉得这个递归应该可以吧。。为此还把MAXN由10000改成600改成90。。才发现题目最后说一行最多80。。。)之后WA有多种原因,样例之间有空行,每个样例中每个数据间有空格但是最后一个数据没有空格,忘了注释freopen,简直WA的原因大全了!!最主要的还有最后一个找了好久才找到的原因是,开始我都是以scanf后跟的getchar来判断的,即dfs中注释掉的那个if语句,即如果输入是-1且其后是EOF则输入结束。这里假设了-1后直接就结束,没有空格没有换行。。从拷贝样例数据时来看,-1后面的确像是那样,但题目总没有提到。。。

注意:结束行-1后可能有空格或换行,不是紧跟EOF

看了美网贝贝两盘胜A拉,好样的,希望再接再厉,娜姐不在的情况扛起大旗啊,近几年的代表作了吧

Code:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXN 90

typedef struct node
{
 int data;
 int wz;
 struct node *left,*right;
}Node;

void print();
Node* dfs(int hz,bool *flag);
Node* newnode();
void remove_tree(Node *root);

int spwz[MAXN];
int first;

int main()
{
 //freopen("699.in","r",stdin);
 //freopen("699.out","w",stdout);
 int cnt=1;
 while(1)
 {
  memset(spwz,0,sizeof(spwz));
  bool flag=0;
  first=1;
  Node *root=dfs(0,&flag);
  if(flag) break;
  printf("Case %d:\n",cnt++);
  print();
  remove_tree(root);
 }
 return 0;
}

void print()
{
 int i=0;
 for(;i<MAXN;++i)
 {
  if(spwz[i]) { printf("%d",spwz[i]); break;}
 }
 for(i++;i<MAXN;++i)
  if(spwz[i]) printf(" %d",spwz[i]);
 printf("\n\n");
}

Node* dfs(int hz,bool *flag)
{
 int num;
 scanf("%d",&num);//char c=getchar();
 Node *u=newnode();
 u->data=num;
 u->wz=hz;
 //if(x!=1 || (num==-1 && c==EOF)) {*flag=1; return NULL;}
 if(first && num==-1) {*flag=1; return NULL;}
 first=0;
 if(num<0) return NULL;
 if(num>0)
 {
  spwz[MAXN/2+hz]+=num;
  u->left=dfs(hz-1,flag);
  u->right=dfs(hz+1,flag);
  return u;
 }
}

Node* newnode()
{
 Node *u=(Node*)malloc(sizeof(Node));
 if(u!=NULL)
 {
  u->data=u->wz=0;
  u->left=u->right=NULL;
 }
 return u;
}

void remove_tree(Node *root)
{
 if(root!=NULL)
 {
  remove_tree(root->left);
  remove_tree(root->right);
  free(root);
 }
}
时间: 2024-11-03 22:18:48

UVa 699 落叶的相关文章

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

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

uva 699

我们可以把它直接考虑是个一维数组,对每个点向两边扩展,记录数据在数组中, 就是DFS #include <stdio.h> int a[81],left,right; void sort(int num,int pos) {int x,y;  if (num!=-1)  {if (pos<left) left=pos;   if (pos>right) right=pos;   a[pos]+=num;   scanf("%d",&x);   sort(

UVA 699(二叉树建树与遍历)

M - The Falling Leaves Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Appoint description:  System Crawler  (2014-02-08) Description  The Falling Leaves  Each year, fall in the North Central region is accompanied

UVa 699 The Falling Leaves(递归建树)

题意  假设一棵二叉树也会落叶  而且叶子只会垂直下落   每个节点保存的值为那个节点上的叶子数   求所有叶子全部下落后   地面从左到右每堆有多少片叶子 和上一题有点像  都是递归输入的  一个节点(设水平位置为p)  则它的左右儿子节点的水平位置分别为  p-1  p+1   也是可以边输入边处理的  输入完也就得到答案了   注意每个样例后面都有一个空行  包括最后一个 #include<cstdio> #include<cstring> using namespace s

UVa 699.The Falling Leaves【7月23】

The Falling Leaves Each year, fall in the North Central region is accompanied by the brilliant colors of the leaves on the trees, followed quickly by the falling leaves accumulating under the trees. If the same thing happened to binary trees, how lar

uva 699 The Falling Leaves(建二叉树同一时候求和)

本来看着挺难的.大概是由于我多瞟了一眼题解,瞬间认为简单多了.做题就得这样,多自己想想.如今是 多校联赛,然而我并不会做. .. .慢慢来,一直在努力. 分析: 题上说了做多不会超过80行.所以能够开一个数组.这里我是把根节点作为第42个数,能够在建树的同一时候求 出那一列全部数值的和左孩子节点减一,右孩子节点加一.. .写的时候中间出了点小bug,忘了给flag重置0了,调 了好久.. . 第一次提交wa了,由于没有换行,题目要求结果之间有一行空行的. . . 贴代码: #include<st

UVA 699 The Falling Leaves

#include<cstdio> #include<iostream> #include<queue> #include<cstring> #include<string> #include<math.h> #include<stack> #include<cstdlib> #include<map> #include<algorithm> #include<cctype>

UVa 699 (二叉树) The Falling Leaves

题意: 按先序方式输入一棵二叉树,节点是带权的,左孩子在父节点的左一个单位,右孩子在父节点的右一个单位,从左到右输出相同水平位置节点之和. 分析: 做了好几道二叉树的题,代码应该也很好理解了.这里maxn开始设了200.500都RE,后来索性开了2000,AC了 紫书上面init函数最后应该加一句 return true; 1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstri

The Falling Leaves UVA 699

说说: 这道题非常简单,本质上就是二叉树的先序遍历.只需要建立一个数组,然后将初始位置放在数组中心.然后进入左子树的根节点,向数组左侧移动一位,添加当前节点所含的值,同理进入右子树的根节点,向数组右侧移动一位,添加当前节点所含的值.并标记好到达过的数组的左右边界,最后将边界内数组的值输出即可. 源代码: #include <stdio.h> #include <string.h> #define MAXN 200 int piles[MAXN]; int leftmost,righ