题面
The Closest Pair
题面翻译(原题面翻译的太好,我来重新翻译一下)
目前,Tiny 正在学习计算几何。当尝试解决一个名为 “The Closest Pair Of Points In The Plane” 的问题时,他发现给出错误时间复杂度的代码被 Accepted 而不是 Time Limit Exceeded。
问题如下。鉴于 n n n 个点,找到一对距离最小的点。 ( x 1 , y 1 ) \left ( x_1,y_1 \right ) (x1,y1) 与 ( x 2 , y 2 ) \left ( x_2,y_2 \right ) (x2,y2) 两点间距离为 ( x 2 − x 1 ) 2 + ( y 2 − y 1 ) 2 \sqrt{\left ( x_2-x_1 \right )^{2}+\left ( y_2-y_1 \right )^{2} } (x2−x1)2+(y2−y1)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
这里 t o t tot tot 可以看作是代码的运行时间。由于计算机每秒只能运行有限数量的操作,因此 t o t tot tot 不应超过 k k 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 n n points in the plane, find a pair of points between which the distance is minimized. Distance between ( x 1 , y 1 ) (x_{1},y_{1}) (x1,y1) and ( x 2 , y 2 ) (x_{2},y_{2}) (x2,y2) is ( x 2 − x 1 ) 2 + ( y 2 − y 1 ) 2 \sqrt{\left ( x_2-x_1 \right )^{2}+\left ( y_2-y_1 \right )^{2} } (x2−x1)2+(y2−y1)2.
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, t o t tot 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, t o t tot tot should not be more than k k 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 n n and $k ( 2 ≤ n ≤ 2000 , 1 ≤ k ≤ 1 0 9 2\le n\le 2000,1\le k\le 10^{9} 2≤n≤2000,1≤k≤109 ).
输出格式
If there doesn’t exist such a data which let the given code get TLE, print “no solution” (without quotes); else print n n n lines, and the i i i -th line contains two integers x i , y i x_{i},y_{i} xi,yi ( ∣ x i ∣ , ∣ y i ∣ ≤ 1 0 9 ) (|x_{i}|,|y_{i}| \le 10^{9}) (∣xi∣,∣yi∣≤109) representing the coordinates of the i i i -th point.
The conditions below must be held:
- All the points must be distinct.
- ∣ x i ∣ , ∣ y i ∣ ≤ 1 0 9 |x_{i}|,|y_{i}| \le 10^{9} ∣xi∣,∣yi∣≤109 .
- After running the given code, the value of $ tot $ should be larger than k k k .
样例 #1
样例输入 #1
4 3
样例输出 #1
0 0
0 1
1 0
1 1
样例 #2
样例输入 #2
2 100
样例输出 #2
no solution
题解
思路
t o t tot tot 是代码的循环次数,所以根据代码得出 t o t tot tot 最大为 n 2 − n 2 \dfrac{n^{2}-n}{2} 2n2−n,即所有的点 x x x 坐标相等。
因此,当
k
>
t
o
t
k > tot
k>tot 时,就一定 cout << "no solution"
。当
k
≤
t
o
t
k \le tot
k≤tot 时,就应当将
x
x
x 坐标尽量相等,
y
y
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;
}