Thứ Ba, 27 tháng 11, 2012

Problem Building Bridge

Link: http://codeforces.com/problemset/problem/250/D

D. Building Bridge
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
Two villages are separated by a river that flows from the north to the south. The villagers want to build a bridge across the river to make it easier to move across the villages.
The river banks can be assumed to be vertical straight lines x = a and x = b (0 < a < b).
The west village lies in a steppe at point O = (0, 0). There are n pathways leading from the village to the river, they end at points Ai = (a, yi). The villagers there are plain and simple, so their pathways are straight segments as well.
The east village has reserved and cunning people. Their village is in the forest on the east bank of the river, but its exact position is not clear. There are m twisted paths leading from this village to the river and ending at points Bi = (b, y'i). The lengths of all these paths are known, the length of the path that leads from the eastern village to point Bi, equals li.
The villagers want to choose exactly one point on the left bank of river Ai, exactly one point on the right bank Bj and connect them by a straight-line bridge so as to make the total distance between the cities (the sum of |OAi| + |AiBj| + lj, where |XY| is the Euclidean distance between points X and Y) were minimum. The Euclidean distance between points (x1, y1) and (x2, y2) equals .
Help them and find the required pair of points.
Input
The first line contains integers nmab (1 ≤ n, m ≤ 1050 < a < b < 106).
The second line contains n integers in the ascending order: the i-th integer determines the coordinate of point Ai and equals yi (|yi| ≤ 106).
The third line contains m integers in the ascending order: the i-th integer determines the coordinate of point Bi and equals y'i (|y'i| ≤ 106).
The fourth line contains m more integers: the i-th of them determines the length of the path that connects the eastern village and point Bi, and equals li (1 ≤ li ≤ 106).
It is guaranteed, that there is such a point C with abscissa at least b, that |BiC| ≤ li for all i (1 ≤ i ≤ m). It is guaranteed that no two points Ai coincide. It is guaranteed that no two points Bi coincide.
Output
Print two integers — the numbers of points on the left (west) and right (east) banks, respectively, between which you need to build a bridge. You can assume that the points on the west bank are numbered from 1 to n, in the order in which they are given in the input. Similarly, the points on the east bank are numbered from 1 to m in the order in which they are given in the input.
If there are multiple solutions, print any of them. The solution will be accepted if the final length of the path will differ from the answer of the jury by no more than 10 - 6 in absolute or relative value.
Sample test(s)
input
3 2 3 5
-2 -1 4
-1 2
7 3
output
2 2


Thuật toán: Cố định một điểm bên một bờ, dùng lower_bound tìm vị trí điểm của bờ bên cạnh. Từ đó min hóa trị cần tìm.

Code:

/*
Coder : Nguyen Duc Tam
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<set>
#include<vector>
#include<utility>
#include<map>
#include<list>
#include<queue>
#include<deque>
#include<stack>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<iomanip>
#include<ctime>

using namespace std;

#define REP(i, start, end, step) for(int i = start; i < end; i += step)
#define DOWN(i, start, end, step) for(int i = start; i > end; i -= step)
#define FOR(it,c) for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define ALL(c) (c).begin(), (c).end()
#define SZ(x) ((int)(x).size())
#define X first
#define Y second

#define L(x,i) ((x) << (i))
#define R(x,i) ((x) >> (i))
#define AND(a,b) ((a) & (b))
#define OR(a,b) ((a) | (b))
#define XOR(a,b) ((a) ^ (b))
#define NOT(a) (~(a))
#define SB(x,i) (OR((x), L(1, (i)))) // x | 1 << i
#define CB(x,i) (AND((x),NOT(L(1,(i))))) // x & ~(1 << i)
#define TB(x,i) (AND((x), L(1,(i)))) // x & (1 << i)

#define FILL(a,val) memset(a,val,sizeof(a));
#define INIT(a,l,r,val) REP(i,l,r,1) (a)[i] = val;
#define DIG(c) (int)((c) - '0')
#define CHR(c) (char)((c) + '0')
#define LOW(c) (char)((c) + 32)
#define UPP(c) (char)((c) - 32)

#define SQR(a) (a) * (a)

#define EPS 1e-7
#define OO 1000000005
#define N 100005

const int DAY[13] = {-1,31,29,31,30,31,30,31,31,30,31,30,31};
const int dx4[4] = {};
const int dy4[4] = {};
const int dx8[8] = {};
const int dy8[8] = {};


typedef pair<int,int> II;
typedef pair<II,int> D;
typedef long long LL;
typedef unsigned long long ULL;
typedef unsigned char UC;

vector<int>::iterator it, low, up; // using FOR, lower_bound, upper_bound
pair<vector<int>,vector<int> > bound; // using function equal_range(first, last, x)

int n,m,a,b,y[N],y_[N],l[N],resA,resB;
double res = -1.0;

int main()
{
#define Off  true
if(Off)
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
}
//Read input
cin >> n >> m >> a >> b;
REP(i,0,n,1)
scanf("%d",&y[i]);
REP(i,0,m,1)
scanf("%d",&y_[i]);
REP(i,0,m,1)
scanf("%d",&l[i]);

//process
double temp = 0.0, ytemp, val;
int d = b - a;
REP(i,0,m,1)
{
ytemp =  ((double)a / b) * y_[i];
//cout << "ytemp = " << ytemp << endl;
int pos = lower_bound(y, y + n, ytemp) - y;
REP(j, max(0, pos - 1), min(n - 1, pos + 1) + 1,1)
{
val = sqrt((double)(SQR((LL)y[j]) + SQR((LL)a)));
val += sqrt((double)(SQR((LL)d) + SQR((LL)(y_[i] - y[j]))));
val += l[i];
if(res == -1.0 || res > val)
{
res = val;
resA = j;
resB = i;
}
}
}
cout << resA + 1 << " " << resB + 1 << endl;
return 0;
}





Không có nhận xét nào:

Đăng nhận xét