K-Dimensional Foil II HihoCoder - 1835 思維+二分

"K-Dimensional Foil" is a dimensional weapon. Its function is quite easy: It can ascend a region in 3D space to K (K≥3) dimension. One can use it to give the enemy unexpected attack. It was called "The Ultimate Weapon".

--"Remembrance of Mars's Past"

You are the chief technology officer in the space fleet, and your fleet was just suffered from the attack of the K-Dimensional Foil. The good news was that you have found the key parameter K, the dimension of the space. But staying in high dimensional space is very dangerous, you must destroy the K-Dimensional Foil as fast as possible.

You have n spaceships, spaceship i locates at si = (si,1, …, si,K), and the K-Dimensional  Foil is a 1-norm ball with center c = (c1, …, cK) and radius r, a 1-norm ball with center c and radius r is a point set defined as
{x |  d(x, c)  ≤ r}, d(x, c) =∑| xi - ci |

In the formula above, the coordinate of point x is (x1, x2 … xK)

Your spaceships will fire laser cannon to destroy the K-Dimensional Foil. The energy decay is very quick with the increase of the distance in the high dimensional space, so for every spaceship, you want to find the closest point (in Euclidean distance) on the K-Dimensional Foil. It's guaranteed that no spaceship is in the K-Dimensional Foil initially.

Input

The first line of the input is an integer T (T ≤ 100), the number of the test cases.

For each test case, the first line contains two integer n, K (1 ≤ n ≤ 50, 1 ≤ K ≤ 100), the number of spaceship in your fleet and the dimension of the space.

Then one line contains an integer r (1 ≤ r ≤ 104 ), the radius of the K-Dimensional Foil.

Then one line contains K integers c1, … cK, meaning the coordinate of the center of the K-Dimensional Foil.

Then n lines follow. Each line contains K integers si,1, …, si,K, meaning the coordinate of a spaceship.

All the absolute values of the coordinate are smaller than 104.

Output

For each test case, output n lines. The ith line contains K numbers representing the coordinate of the closest point on the K-Dimensional Foil to the ith spaceship. The absolute error between your output and the answer should be less than 10-4

Sample Input

1
2 2
1
0 0
1 1
1 3

Sample Output

0.50 0.50
0.00 1.00

Hint

The K-Dimensional Foil in the sample was a square with vertex: (1,0), (0,1), (-1,0), (0,-1)

This problem is special judged.

題意:T組樣例,給定n,k,表示有n個點,k維空間。在給定一個r,以及座標(r1,r2,...,rk)表示圓心,r表示半徑(曼哈頓距離),構成一個物體。接下來給定n個點的k維座標,問這n個點距離這個物體的最短距離是多少。

思路:首先我們把所有座標平移,使得物體的心在座標原點上。那麼n個點的座標爲(s1-r1,s2-r2,...sk-rk)。我們假設xi=si-ri,

點(x1,x2,...xk)距物體最近的點爲(y1,y2,...,yk),那麼問題就轉化成了這兩點之間的距離。我們已知|y1|+|y2|+...+|yk|=r,|x1|+|x2|+....+|xk|=sum。dis^2=(x1-y1)^2+(x2-y2)^2+...+(xk-yk)^2。要使dis最小,我們易知xi與yi同號。

那麼dis^2=(|x1|-|y1|)^2+(|x2|-|y2|)^2+...+(|xk|-|yk|)^2。假設ai=xi-yi,那麼dis^2=|a1|^2+|a2|^2+...+|ak|^2。我們已知|a1|+|a2|+...+|ak|=sum-r。要使dis最小,如果用貪心的思想,|ai|取(sum-r)/k時最小。但是有一個問題:當|xi|<(sum-r)/k時|ai|不可能取到這個值,因爲xi與yi同號。於是問題就轉化爲了這樣一個問題:有水sum-r體積,有n個杯子,每個杯子容積|xi|-|yi|,將這些水到了這些杯子裏,使得價值最小,每杯水的價值爲杯中水體積的平方。我們可以二分找杯中水體積的最大值,具體實現看代碼。

#include<bits/stdc++.h>
using namespace std;
const int maxn=110;
int c[maxn],s[maxn];
double y[maxn],x[maxn];
const double eps=1e-6;
int main()
{
	int t,n,k,r;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d%d",&n,&k,&r);
		for(int i=1;i<=k;i++) scanf("%d",&c[i]);
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=k;j++)
			{
				scanf("%d",&s[j]);
				x[j]=abs(s[j]-c[j]);
			}
			double L=0,R=1e4+100,mid;
			while(R-L>eps)
			{
				mid=(L+R)/2.0;
				double sum=0.0;
				for(int j=1;j<=k;j++)
				{
					sum+=max(0.0,x[j]-mid);
				}
				if(sum<=r) R=mid;
				else L=mid;
			}
			for(int j=1;j<=k;j++)
			{
				if(x[j]>L) x[j]=L;
				if(s[j]-c[j]>0)
				{
					if(j==k) printf("%.4lf\n",s[j]-x[j]);
					else printf("%.4lf ",s[j]-x[j]);
				}
				else
				{
					if(j==k) printf("%.4lf\n",s[j]+x[j]);
					else printf("%.4lf ",s[j]+x[j]);
				}
			}
		}
	}
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章