標籤:uva 遞迴 落葉
題意:題意我都快記不清了!!!被坑好久。。就是從根結點開始,每往左走一步,橫座標減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 90typedef 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); } }
UVa 699 落葉