Codeforces(429D - Tricky Function)最近点对问题
2014-05-12 13:43
323 查看
D. Tricky Function
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
Iahub and Sorin are the best competitive programmers in their town. However, they can't both qualify to an important contest. The selection will be made with the help of a single problem. Blatnatalag, a friend of Iahub, managed to get hold of the problem before
the contest. Because he wants to make sure Iahub will be the one qualified, he tells Iahub the following task.
You're given an (1-based) array a with n elements.
Let's define function f(i, j) (1 ≤ i, j ≤ n) as (i - j)2 + g(i, j)2.
Function g is calculated by the following pseudo-code:
Find a value mini ≠ j f(i, j).
Probably by now Iahub already figured out the solution to this problem. Can you?
Input
The first line of input contains a single integer n (2 ≤ n ≤ 100000).
Next line contains n integers a[1], a[2],
..., a[n] ( - 104 ≤ a[i] ≤ 104).
Output
Output a single integer — the value of mini ≠ j f(i, j).
Sample test(s)
input
output
input
output
解法:可以将结果转化为求(i,sum(i))最近点对问题。sum(i)为前缀1-i之和;
代码:
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
Iahub and Sorin are the best competitive programmers in their town. However, they can't both qualify to an important contest. The selection will be made with the help of a single problem. Blatnatalag, a friend of Iahub, managed to get hold of the problem before
the contest. Because he wants to make sure Iahub will be the one qualified, he tells Iahub the following task.
You're given an (1-based) array a with n elements.
Let's define function f(i, j) (1 ≤ i, j ≤ n) as (i - j)2 + g(i, j)2.
Function g is calculated by the following pseudo-code:
int g(int i, int j) { int sum = 0; for (int k = min(i, j) + 1; k <= max(i, j); k = k + 1) sum = sum + a[k]; return sum; }
Find a value mini ≠ j f(i, j).
Probably by now Iahub already figured out the solution to this problem. Can you?
Input
The first line of input contains a single integer n (2 ≤ n ≤ 100000).
Next line contains n integers a[1], a[2],
..., a[n] ( - 104 ≤ a[i] ≤ 104).
Output
Output a single integer — the value of mini ≠ j f(i, j).
Sample test(s)
input
4 1 0 0 -1
output
1
input
2
1 -1
output
2
解法:可以将结果转化为求(i,sum(i))最近点对问题。sum(i)为前缀1-i之和;
代码:
/****************************************************** * author:xiefubao *******************************************************/ #pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <vector> #include <algorithm> #include <cmath> #include <map> #include <set> #include <stack> #include <string.h> //freopen ("in.txt" , "r" , stdin); using namespace std; #define eps 1e-8 const double pi=acos(-1.0); typedef long long LL; const int Max=10100; const int INF=1000000007; struct point { double x,y; int lable; } ; point points[1001000]; bool operator<(const point& a,const point& b) { if(a.x!=b.x) return a.x<b.x; else return a.y<b.y; } bool compareY(const point& a,const point& b) { return a.y<b.y; } double getDistance(const point& a,const point& b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } double getMiniDistance(int left,int right) { if(left==right) return 1000000000000; if(right-left==1) { if(points[left].lable^points[right].lable) return getDistance(points[left],points[right]); else return 1000000000000; } int mid=(left+right)/2; double num=min(getMiniDistance(left,mid),getMiniDistance(mid+1,right)); double mLine=points[mid].x; int L=mid; while(L>left&&mLine-points[L].x<=num) L--; int R=mid+1; while(R<right&&points[R].x-mLine<=num) R++; sort(points+L,points+R+1,compareY); for(int i=L; i<=R; i++) { for(int j=i+1; j<=min(R,i+5); j++) { if(points[j].y-points[i].y>=num) break; if(points[j].lable^points[i].lable) { num=min(num,getDistance(points[i],points[j])); } } } return num; } int main() { int T; scanf("%d",&T); for(int i=0; i<T; i++) { int N; scanf("%d",&N); for(int i=0; i<N; i++) { scanf("%lf%lf",&points[i].x,&points[i].y); points[i].lable=0; } for(int i=N; i<N*2; i++) { scanf("%lf%lf",&points[i].x,&points[i].y); points[i].lable=1; } sort(points,points+2*N); printf("%.3f\n",getMiniDistance(0,2*N-1)); } return 0; }
相关文章推荐
- Codeforces-429-2-C Leha and Function
- 最近碰到的一些 SSL 问题记录
- 最近发现一些double不能做金融计算的问题
- 最近工作中遇到的2个问题
- 最近开发遇到一个传值和引用问题 记录一下
- poj 1330 【最近公共祖先问题+fa[]数组+ 节点层次搜索标记】
- 最近访问用户问题的实现
- 1 数据结构类-最近公共祖先LCA问题
- 最近用VC/MFC写程序遇到的问题以及解决方案
- 最近遇到一个很蹩脚的问题
- 最近点对问题python解法
- $(function(){});里的方法无效问题
- codeforces 429 On the Bench dp+排列组合 限制相邻元素,求合法序列数。
- function 将数据点分配到最近的聚类中心
- CodeForces 283C Coin Troubles 背包问题 分析问题
- CodeForces 659 B. Qualifying Contest(结构体排序的问题)
- 最近学习过程中遇到的问题,记录一下
- Js中的$(function());问题详解
- 总结一下,最近工作中的问题
- Codeforces 429B - Working out (DP)