题解:CF311A The Closest Pair
题面
The Closest Pair
题面翻译(洛谷翻译的太好,我来重新翻译)
目前,Tiny 正在学习计算几何。当尝试解决一个名为 “The Closest Pair Of Points In The Plane” 的问题时,他发现给出错误时间复杂度的代码被 Accepted 而不是 Time Limit Exceeded。
问题如下。鉴于 \(n\) 个点,找到一对距离最小的点。\(\left ( x_1,y_1 \right )\) 与 \(\left ( x_2,y_2 \right )\) 两点间距离为 $\sqrt{\left ( x_2-x_1 \right )^{2}+\left ( y_2-y_1 \right )^{2} } $。
意外代码的伪代码如下:
input n
for i from 1 to n
input 第 i 个点的坐标
通过升序 x 坐标和升序 y 坐标来对数组 p[] 进行排序
d=INF //INF 是一个足够大的数
tot=0
for i from 1 to n
for j from (i+1) to n
++tot
if (p[j].x-p[i].x>=d)
then break
//请注意,“break” 只是为了跳过 “for j” 的循环
d=min(d,distance(p[i],p[j]))
output d
这里 \(tot\) 可以看作是代码的运行时间。由于计算机每秒只能运行有限数量的操作,因此 \(tot\) 不应超过 \(k\),以免超出时间限制。
你是一个了不起的黑客。您能否帮助 Tiny 生成测试数据并让代码获得 Time Limit Exceeded?(奇怪的要求)
题目描述
Currently Tiny is learning Computational Geometry. When trying to solve a problem called "The Closest Pair Of Points In The Plane", he found that a code which gave a wrong time complexity got Accepted instead of Time Limit Exceeded.
The problem is the follows. Given $ n $ points in the plane, find a pair of points between which the distance is minimized. Distance between $ (x_{1},y_{1}) $ and $ (x_{2},y_{2}) $ is
.
The pseudo code of the unexpected code is as follows:
input n
for i from 1 to n
input the i-th point's coordinates into p[i]
sort array p[] by increasing of x coordinate first and increasing of y coordinate second
d=INF //here INF is a number big enough
tot=0
for i from 1 to n
for j from (i+1) to n
++tot
if (p[j].x-p[i].x>=d) then break //notice that "break" is only to be
//out of the loop "for j"
d=min(d,distance(p[i],p[j]))
output d
Here, $ tot $ can be regarded as the running time of the code. Due to the fact that a computer can only run a limited number of operations per second, $ tot $ should not be more than $ k $ in order not to get Time Limit Exceeded.
You are a great hacker. Would you please help Tiny generate a test data and let the code get Time Limit Exceeded?
输入格式
A single line which contains two space-separated integers $ n $ and $ k $ ( $ 2\le n\le 2000 $ , $ 1\le k\le 10^{9} $ ).
输出格式
If there doesn't exist such a data which let the given code get TLE, print "no solution" (without quotes); else print $ n $ lines, and the $ i $ -th line contains two integers $ x_{i},y_{i} $ $ (|x_{i}|,|y_{i}| \le 10^{9}) $ representing the coordinates of the $ i $ -th point.
The conditions below must be held:
- All the points must be distinct.
- $ |x_{i}|,|y_{i}| \le 10^{9} $ .
- After running the given code, the value of $ tot $ should be larger than $ k $ .
样例 #1
样例输入 #1
4 3
样例输出 #1
0 0
0 1
1 0
1 1
样例 #2
样例输入 #2
2 100
样例输出 #2
no solution
题解
思路
\(tot\) 是代码的循环次数,所以根据代码得出 \(tot\) 最大为 \(\dfrac{n^{2}-n}{2}\),即所有的点 \(x\) 坐标相等。
因此,当 \(k > tot\) 时,就一定 cout << "no solution"。当 \(k \le tot\) 时,就应当将 \(x\) 坐标尽量相等,\(y\) 坐标随机但不相等。
代码
#include<bits/stdc++.h>
using namespace std;
int n, k;
int main() {
cin >> n >> k;
if (n * (n - 1) / 2 <= k)
cout<<"no solution\n";
else
for (int i = 1; i <= n; i++)
cout << 114514 << " " << i << "\n";
return 0;
}

浙公网安备 33010602011771号