POJ-2182-Low Cows

POJ-2182-Low Cows

传送门

这道题是一道线段树。模板线段树。

不慌。没有暴力不能解决的问题。
8000的数据还是可以暴力跑一下的嘻嘻。

题目大意:已知每头牛前面有几头牛比他矮。问原序列。

pre[]保存前面有几头牛比当前矮
暴力的话从后往前处理即可。答案就是第pre[]+1大的数字,另外一个数组num[]保存1~n的值,把处理过的数值直接赋值为-1就行,在剩下的序列中选择即可。

poj万能头CE了,改改就行

暴力代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 8e3 + 10;

int n;
int pre[N];
int ans[N];
int num[N];

int main()
{
	cin >> n;
	pre[1] = 0;
	for (int i = 1; i <= n; i++)
	{
		num[i] = i;
	}
	for (int i = 2; i <= n; i++)
	{
		scanf ("%d", &pre[i]);
	}
	for (int i = n; i >= 1; i--)
	{
		int k = 0;
		for (int j = 1; j <= n; j++)
		{
			if (num[j] != -1)
			{
				k++;
				if (k == pre[i] + 1)
				{
					ans[i] = num[j];
					num[j] = -1;
					break;
				}
			}
		}
	}
	for (int i = 1; i <= n; i++)
	{
		cout << ans[i] << endl;
	}
	return 0;
}

时间复杂度O(n^2);

线段树代码一样的思路,从后往前。就是时间复杂度低些:

其一是普通二叉树,含结构体

代码部分:

#include <iostream>
#include <cstdio>
using namespace std;
const int N = 1e4 + 10;

struct node
{
	int l, r;
	int len;
}tree[4 * N];
int pre[N];
int ans[N];
int n;

void BuildTree(int left, int right, int u)
{
	tree[u].l = left;
	tree[u].r = right;
	tree[u].len = right - left + 1;
	if (left == right)
	{
		return ;
	}
	BuildTree(left, (left + right) >> 1, u << 1);
	BuildTree(((left + right) >> 1) + 1, right, (u << 1) + 1);
}

int query(int u, int num)
{
	tree[u].len--;
	if (tree[u].l == tree[u].r)
	{
		return tree[u].l;
	}
	if (tree[u << 1].len >= num)//左子树的个数足够,访问左子树 
	{
		return query(u << 1, num);
	}
	else//不够,访问右子树 
	{
		return query((u << 1) + 1, num - tree[u << 1].len);
	}
}

int main()
{
	cin >> n;
	pre[1] = 0;
	for (int i = 2; i <= n; i++)
	{
		scanf ("%d", &pre[i]);
	}
	BuildTree(1, n, 1);
	for (int i = n; i >= 1; i--)
	{
		ans[i] = query(1, pre[i] + 1);
	}
	for (int i = 1; i <= n; i++)
	{
		cout << ans[i] << endl;
	}
	return 0;
}

完全二叉树实现:直接访问地址效率较高

#include <cstdio>
#include <iostream>
#include <cmath>
using namespace std;
const int N = 1e4 + 10;

int pre[N];
int ans[N];
int tree[4 * N];
int n;

void BuildTree(int n, int last)
{
	for (int i = last; i < last + n; i++)
	{
		tree[i] = 1;
	}
	while (last != 1)
	{
		for (int i = last / 2; i < last; i++)
		{
			tree[i] = tree[i * 2] + tree[i * 2 + 1];
		}
		last /= 2;
	}
}

int query(int u, int num, int last)
{
	tree[u]--;
	if (!tree[u] && u >= last)
	{
		return u;
	}
	if (tree[u << 1] >= num)
	{
		return query(u << 1, num, last);
	}
	else
	{
		return query((u << 1) + 1, num - tree[u << 1], last);
	}
}

int main()
{
	cin >> n;
	pre[1] = 0;
	int last = 1 << ((int)(log(n) / log(2)) + 1);//最底层最左边的结点 
	for (int i = 2; i <= n; i++)
	{
		scanf ("%d", &pre[i]);
	}
	BuildTree(n, last);
	for (int i = n; i >= 1; i--)
	{
		ans[i] = query(1, pre[i] + 1, last) - last + 1;
	}
	for (int i = 1; i <= n; i++)
	{
		cout << ans[i] << endl;
	}
	return 0;
}
发布了112 篇原创文章 · 获赞 3 · 访问量 2638

猜你喜欢

转载自blog.csdn.net/qq_44624316/article/details/104947172
今日推荐