算法学习记录:[NOIP2011]铺地毯

题目链接:

  https://ac.nowcoder.com/acm/contest/20960/1016

解题思路:

最直观的方法,因为编号大的地毯一定更靠后,所以直接用编号进行标记。

时间复杂度分析:

该代码时间复杂度为\(O(N^2)\),有\(10^4\times(10^5)^2\),评测oj每1秒能接受的时间复杂度为: \([10^8,10^9]\)
所以下代码一定TLE。

TLE代码

#include <iostream>

using namespace std;

// 编号大的一定在上面,所以依次暴力枚举所有地毯

const int N = 10005;

int n, cnt = 1, ans;
int x, y, a, b;		// (x,y), 分别为x,y方向的长度
int m[N][N];

int main()
{
	cin >> n;
	while (n -- )
	{
		cin >> x >> y >> a >> b;
		for (int i = x; i <= x + a; ++ i)
			for (int j = y; j <= y + b; ++ j)
				m[i][j] = cnt;
		cnt ++ ;
	}

	cin >> x >> y;
	cout << m[x][y];

	return 0;
}

AC代码

我们没有必要维护每张地毯的所有点,因为最后,我们想要得到的答案永远只是一个点
我们只要针对该点确定范围即可

#include <iostream>

using namespace std;

const int N = 10005;

int n;
int x, y, a, b;
int m[N][N];

int main()
{
	cin >> n;
	
	for (int i = 1; i <= n; ++ i)
	{
		cin >> x >> y >> a >> b;
		m[i][0] = x, m[i][1] = x + a, m[i][2] = y, m[i][3] = y + b;
	}
	
	cin >> x >> y;
	for (int i = n; i > 0; -- i)
		if (x >= m[i][0] && x <= m[i][1] && y >= m[i][2] && y <= m[i][3])
		{ cout << i; break; }

	return 0;
}
posted @ 2023-05-20 10:29  想个昵称好难ABCD  阅读(28)  评论(0)    收藏  举报