Computational Geometry?
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 582 Accepted Submission(s): 199
Problem Description
Computational geometry is a branch of computer science devoted to the study of algorithms which can be stated in terms of geometry. It often comes up with charming shapes and ideas.
In this problem, our poor princess is trapped in a castle by some bad guys again, yeah, again. So, let's seize the chance to be a hero.
Right now, the beautiful princess is in the original point of a Cartesian coordinate system, for simplification, the castle is treated as a coordinate system, like a common computational geometry problem.
There is a bomb which can be exploded anytime, and it locates at (Xo, Yo) in the castle. To save the princess, we need design a route for her to leave away the bomb as far as possible. But she already has a plan written on her notebook, which contains some vectors, and she insists on escaping in the vectors’ direction one by one, that is, if she is in point(0, 0), and the vector is (X, Y), she will be in point(X, Y) if she escapes in this vector.
You get her notebook now, and find princess's plan is a not a good plan sometimes. Then you decide to help the princess to make some slight modification, you can change the order of those vectors, and/or reverse some vectors, that is, change vector (X, Y) to vector (-X, -Y).
We want to know the maximum distance to the bomb after modification.
In this problem, our poor princess is trapped in a castle by some bad guys again, yeah, again. So, let's seize the chance to be a hero.
Right now, the beautiful princess is in the original point of a Cartesian coordinate system, for simplification, the castle is treated as a coordinate system, like a common computational geometry problem.
There is a bomb which can be exploded anytime, and it locates at (Xo, Yo) in the castle. To save the princess, we need design a route for her to leave away the bomb as far as possible. But she already has a plan written on her notebook, which contains some vectors, and she insists on escaping in the vectors’ direction one by one, that is, if she is in point(0, 0), and the vector is (X, Y), she will be in point(X, Y) if she escapes in this vector.
You get her notebook now, and find princess's plan is a not a good plan sometimes. Then you decide to help the princess to make some slight modification, you can change the order of those vectors, and/or reverse some vectors, that is, change vector (X, Y) to vector (-X, -Y).
We want to know the maximum distance to the bomb after modification.
Input
The first line contains a single integer T, indicating the number of test cases. Each test case begins with three integers N, Xo, Yo. Then N lines following, each line contains two integers, Xi and Yi, indicating a vector.
Technical Specification
1. 1 <= T <= 100
2. 1 <= N <= 100
3. -100 <= Xi, Yi <= 100
4. -10 000 <= Xo, Yo <= 10 000
Technical Specification
1. 1 <= T <= 100
2. 1 <= N <= 100
3. -100 <= Xi, Yi <= 100
4. -10 000 <= Xo, Yo <= 10 000
Output
For each test case, output the case number first, then the distance rounded to three fractional digits.
Sample Input
3 1 1 1 1 1 2 2 3 -1 2 1 -2 3 3 0 2 3 3 2 1 -1
Sample Output
Case 1: 2.828 Case 2: 7.000 Case 3: 9.849
Author
iSea@WHU
Source
题目大意:
给你N个向量,每个向量选择要么走(x,y)要么走(-x,-y);
主人公一开始在(0,0)走,问走到的最终的地方距离(x0,y0)这个点最远的距离是多少?
思路:
设定maxn【i】【j】表示走到了第i个向量,横坐标在位子j的最大纵坐标。
设定minn【i】【j】表示走到了第i个向量,横坐标在位子j的最小纵坐标。
那么其状态转移方程不难写出:
加mid的原因是j会出现负值。
过程维护一下然后最终枚举得到最大距离即可。
Ac代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
int maxn[105][45000];
int minn[105][45000];
double dis(int x,int y,int x2,int y2)
{
double xx=x;
double yy=y;
double xxx=x2;
double yyy=y2;
double ans=sqrt((xx-xxx)*(xx-xxx)+(yy-yyy)*(yy-yyy));
return ans;
}
int main()
{
int t;
int kase=0;
scanf("%d",&t);
while(t--)
{
int n,x0,y0;
scanf("%d%d%d",&n,&x0,&y0);
int mid=45000/2;
for(int i=0;i<=n;i++)
{
for(int j=0;j<=45000;j++)
{
maxn[i][j]=-1000000000;
minn[i][j]=1000000000;
}
}
maxn[0][x0+mid]=y0;
minn[0][x0+mid]=y0;
for(int i=1;i<=n;i++)
{
int x,y;scanf("%d%d",&x,&y);
for(int j=-22000;j<=22000;j++)
{
if(maxn[i-1][j+mid-x]!=-1000000000)maxn[i][j+mid]=max(maxn[i][j+mid],maxn[i-1][j+mid-x]+y);
if(maxn[i-1][j+mid+x]!=-1000000000)maxn[i][j+mid]=max(maxn[i][j+mid],maxn[i-1][j+mid+x]-y);
if(minn[i-1][j+mid-x]!=1000000000)minn[i][j+mid]=min(minn[i][j+mid],minn[i-1][j+mid-x]+y);
if(minn[i-1][j+mid+x]!=1000000000)minn[i][j+mid]=min(minn[i][j+mid],minn[i-1][j+mid+x]-y);
}
}
double ans=0;
for(int j=-22000;j<=22000;j++)
{
if(maxn[n][j+mid]!=-1000000000)ans=max(ans,dis(j,maxn[n][j+mid],0,0));
if(minn[n][j+mid]!=1000000000)ans=max(ans,dis(j,minn[n][j+mid],0,0));
}
printf("Case %d: ",++kase);
printf("%.3f\n",ans);
}
}