OJ超时求助..后序遍历层次遍历两道题都卡点超时

zszv587 2016-09-23 09:45:42
最近在刷OJ,两道题,层次遍历,后序遍历,都有两个点超时....都是非递归写的,实在想不出更快的写法了,求指点.....谢谢!
链接
层次遍历 http://acm.sjtu.edu.cn/OnlineJudge/problem/1040
后序遍历 http://acm.sjtu.edu.cn/OnlineJudge/problem/1039

层次遍历:
#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>

int t[1000000 + 1] = {};
int que[1000000 + 1] = {};

int main (){

int n;
int i;

scanf ( "%d", &n );

for ( i = 1; i <= n - 1; i ++ ){

scanf ( "%d", &t[i] );

}

int s;//start of que
int e;//end of que
int cnt;
int tmp;
int done;

s = 0;
e = 0;
cnt = n;

que[e++] = 0;

while ( s != e ){

/*pop*/
tmp = que[s++];

/*push*/
done = 0;
for ( i = 1; i <= n - 1; i ++ ){

if ( t[i] == tmp ){

que[e++] = i;
done ++;

if ( done == 2 ){

break;

}

}

}

printf ( "%d", tmp );
cnt --;
if ( cnt != 0 ){

printf ( " " );

}


}

printf ( "\n" );

return 0;

}


后序遍历:
#define _CRT_SECURE_NO_WARNINGS 

#include<stdio.h>

int t[30000 + 1] = {};
int pos[30000 + 1] = {};
int stack[30000 + 1] = {};
int visit[30000 + 1] = {};

//int pos ( int x );
//void post ( int i );

int cnt;

int main (){

int n;
int i;
int i1;
int i2;
int i3;
int base;
int sonid;

t[1] = 1;
pos[1] = 1;

scanf ( "%d", &n );

for ( i = 1; i <= n; i ++ ){

scanf ( "%d%d%d", &i1, &i2, &i3 );

base = pos [i1];

if ( i2 != -1 ){

sonid = 2 * base;
t[sonid] = i2;
pos[i2] = sonid;

}
if ( i3 != -1 ){

sonid = 2 * base + 1;
t[sonid] = i3;
pos[i3] = sonid;

}

}

for ( i = 1; i <= n; i ++ ){

printf ( "%d", pos[i] );

if ( i != n ){

printf ( " " );

}

}

printf ( "\n" );

cnt = n;

int sp;//stack pointer
int p;

sp = 0;//begin with 1 in stack
p = 1;

/*go to the leftest one*/
while ( t[p] != 0 ){

sp ++;
stack[sp] = p;
p = 2 * p;//left child

}

while ( sp != 0 ){

p = stack[sp];

if ( t[2 * p + 1] == 0 || visit[p] == 1 ){//no right child or the second time p shows on the top of stack

visit[p] = 1;
sp --;

printf ( "%d", t[p] );

cnt --;

if ( cnt != 0 ){

printf ( " " );

}
else {

printf ( "\n" );

}

}
else {//from the right child, go to the leftest

visit[p] = 1;

p = 2 * p + 1;

while ( t[p] != 0 ){

sp ++;
stack[sp] = p;
p = p * 2;

}



}


}

return 0;

}
...全文
382 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
hijack00 2016-09-26
  • 打赏
  • 举报
回复
OJ中定义静态大数组的话不要放到main函数里面(因为这时数组是在栈上分配的,很容易超出栈的内存范围),可以将这个大数组作为全局变量定义到main函数外面,这时变量就是定义在全局数据区(不会占用栈空间)。 有些OJ在遇到代码中声明了静态大数组时会报错,导致编译通不过。所以一般情况下,如果需要分配很大的数组最好采用动态内存分配。
赵4老师 2016-09-25
  • 打赏
  • 举报
回复
关于自己是否适合编程的很简单的测试: 在报纸或杂志上随便找一段约1000字的文章,在Word中输入一遍。输完后再参考下面答案: A里面有10处以上文字或标点错误 B里面没有文字或标点错误并敢为此跟人打赌 C里面没有文字或标点错误并且字体和排版完全与原稿一致 D打印在半透明的纸上和原稿重叠在一起检查一模一样,且自我感觉很有成就感 A不适合编程(理由:打字准确度偏低、粗心大意) B初级程序员(理由:打字准确度很高、认真细致、自信、理解全角半角概念) C高级程序员(理由:在B的基础上理解字体和排版也是电脑打印的重要因素、但相比D还不够偏执、精益求精、结果可验证) D软件项目经理(理由:能针对项目给出令人信服的细致到极点的需求说明和典型测试用例。用户几乎挑不出毛病。专业!) 如果想从A变成B的话,到我的资源http://download.csdn.net/detail/zhao4zhong1/4084259里面下载“适合程序员的键盘练习”
zycxnanwang 2016-09-24
  • 打赏
  • 举报
回复
引用 7 楼 u014254473 的回复:
[quote=引用 6 楼 zycxnanwang 的回复:]
[quote=引用 5 楼 u014254473 的回复:]
[quote=引用 4 楼 zhao4zhong1 的回复:]
在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。

囧,试了一下,还是超时....
还有什么办法吗>.<[/quote]
晚上, 没事,把你那题AC了,你百度一下顺序存储二叉树的思路,再看看我的代码,估计就差不多了
算法的复杂度不能太高!

#include<iostream>
using namespace std;
#include<cstdio>
#define N 100000

int order[N]; //存储二叉树
int map[N]; //一个映射
int times = 1;
int n;

int postOrder(int head)
{
if (order[head * 2] != -1) postOrder(head * 2);
if (order[head * 2 + 1] != -1) postOrder(head * 2 + 1);

if (times == n)
printf("%d\n", order[head]);
else printf("%d ", order[head]);

times++;
return 0;
}

int main()
{
//freopen("E:/in.txt", "r", stdin);

scanf("%d", &n);

int num, left, right, temp;
for (int i = 0; i < n; i++)
{
scanf("%d%d%d", &num, &left, &right);
if (num == 1)
{
order[1] = 1;
map[1] = 1;
}

temp = map[num];

if (left != -1)
{
order[2 * temp] = left;
map[left] = 2 * temp;
}
else order[2 * temp] = -1;

if (right != -1)
{
order[2 * temp + 1] = right;
map[right] = 2 * temp + 1;
}
else order[2 * temp + 1] = -1;
}

for (int i = 1; i < n; i++)
printf("%d ", map[i]);
printf("%d\n", map[n]);

postOrder(1);
// fclose(stdin);
return 0;
}
[/quote]

我把你的代码交上去,9个run time error,一个超时....哪里ac了....

我之前跟你写的差不多,递归写的,超时两个点,就改成非递归了,还超时两个点.....

[/quote]
我是无语了。。。。。感觉被鄙视了。。。,楼主, 第一个1039题, 血红血红的正确。。。。
zszv587 2016-09-24
  • 打赏
  • 举报
回复
引用 6 楼 zycxnanwang 的回复:
[quote=引用 5 楼 u014254473 的回复:] [quote=引用 4 楼 zhao4zhong1 的回复:] 在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。
囧,试了一下,还是超时.... 还有什么办法吗>.<[/quote] 晚上, 没事,把你那题AC了,你百度一下顺序存储二叉树的思路,再看看我的代码,估计就差不多了 算法的复杂度不能太高!

#include<iostream>
using namespace std;
#include<cstdio>
#define N 100000

int order[N]; //存储二叉树
int map[N]; //一个映射
int times = 1;
int n;

int postOrder(int head)
{
	if (order[head * 2] != -1) postOrder(head * 2);
	if (order[head * 2 + 1] != -1) postOrder(head * 2 + 1);

	if (times == n)
		printf("%d\n", order[head]);
	else printf("%d ", order[head]);

	times++;
	return 0;
}

int main()
{
	//freopen("E:/in.txt", "r", stdin);

	 scanf("%d", &n);

	int num, left, right, temp;
	for (int i = 0; i < n; i++)
	{
		scanf("%d%d%d", &num, &left, &right);
		if (num == 1)
		{
			order[1] = 1;
			map[1] = 1;
		}

		temp = map[num];

		if (left != -1)
		{
			order[2 * temp] = left;
			map[left] = 2 * temp;
		}
		else order[2 * temp] = -1;

		if (right != -1)
		{
			order[2 * temp + 1] = right;
			map[right] = 2 * temp + 1;
		}
		else order[2 * temp + 1] = -1;
	}

	for (int i = 1; i < n; i++)
		printf("%d ", map[i]);
	printf("%d\n", map[n]);

	postOrder(1);
//	fclose(stdin);
	return 0;
}
[/quote] 我把你的代码交上去,9个run time error,一个超时....哪里ac了.... 我之前跟你写的差不多,递归写的,超时两个点,就改成非递归了,还超时两个点.....
paschen 2016-09-23
  • 打赏
  • 举报
回复
这么大的数组肯定不要定义在栈上,应该动态分配
zycxnanwang 2016-09-23
  • 打赏
  • 举报
回复
引用 5 楼 u014254473 的回复:
[quote=引用 4 楼 zhao4zhong1 的回复:] 在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。
囧,试了一下,还是超时.... 还有什么办法吗>.<[/quote] 晚上, 没事,把你那题AC了,你百度一下顺序存储二叉树的思路,再看看我的代码,估计就差不多了 算法的复杂度不能太高!

#include<iostream>
using namespace std;
#include<cstdio>
#define N 100000

int order[N]; //存储二叉树
int map[N]; //一个映射
int times = 1;
int n;

int postOrder(int head)
{
	if (order[head * 2] != -1) postOrder(head * 2);
	if (order[head * 2 + 1] != -1) postOrder(head * 2 + 1);

	if (times == n)
		printf("%d\n", order[head]);
	else printf("%d ", order[head]);

	times++;
	return 0;
}

int main()
{
	//freopen("E:/in.txt", "r", stdin);

	 scanf("%d", &n);

	int num, left, right, temp;
	for (int i = 0; i < n; i++)
	{
		scanf("%d%d%d", &num, &left, &right);
		if (num == 1)
		{
			order[1] = 1;
			map[1] = 1;
		}

		temp = map[num];

		if (left != -1)
		{
			order[2 * temp] = left;
			map[left] = 2 * temp;
		}
		else order[2 * temp] = -1;

		if (right != -1)
		{
			order[2 * temp + 1] = right;
			map[right] = 2 * temp + 1;
		}
		else order[2 * temp + 1] = -1;
	}

	for (int i = 1; i < n; i++)
		printf("%d ", map[i]);
	printf("%d\n", map[n]);

	postOrder(1);
//	fclose(stdin);
	return 0;
}
zszv587 2016-09-23
  • 打赏
  • 举报
回复
引用 1 楼 zycxnanwang 的回复:
数组定义的也太大了,……,这种方法肯定不行! 遍历用递归这是标准方法,没有最好了,
第二个多定义了几个数组也是为了快,空间换时间... 数据规模时题目要求的..... 非递归还超时,问题出在哪呢....0.0
zycxnanwang 2016-09-23
  • 打赏
  • 举报
回复
数组定义的也太大了,……,这种方法肯定不行! 遍历用递归这是标准方法,没有最好了,
zszv587 2016-09-23
  • 打赏
  • 举报
回复
引用 4 楼 zhao4zhong1 的回复:
在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。
囧,试了一下,还是超时.... 还有什么办法吗>.<
赵4老师 2016-09-23
  • 打赏
  • 举报
回复
在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。

69,336

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧