Problem Description 度度熊有一个大小为 MX×MY 的矩形,左下角坐标为 (0,0) ,右上角坐标为 (MX,MY) 。此矩形内有 N 个整数坐标的点 (xi,yi) ,xi 彼此不重复,yi 彼此也不重复。
现在要从每一个点画出一条线段,满足下列条件:
* 线段起点为坐标点,终点在矩形范围的四个边界之一上。 * 线段彼此不能交叉。
现在要让画出的线段的长度总和最小,请输出这个最小的长度总和值。 Input 输入的第一行有一个正整数 T ,代表接下来有几笔测试资料。
对于每笔测试资料: 第一行有三个整数 MX , MY 以及 N 。 接下来的 N 行每行有两个正整数 xi 及 yi 。
* 2≤MX,MY≤106 * 0≤N≤105 * 如果 i≠j ,则保证 xi≠xj 及 yi≠yj * 0<xi<MX * 0<yi<MY * 1≤T≤20 * 至多 2 笔测试资料中的 N>1000 Output 对于每一笔测试资料,请依序各自在一行内输出一个整数,代表可能的最小长度和。 Sample Input 2 4 4 1 2 2 10 7 3 6 3 2 6 9 5 Sample Output 2 5 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6385 分析:连接每个点和离它最近的那条边,由于没有在同一横坐标或纵坐标上的两个点,所以这样的直线是不会交叉的。 #include<stdio.h>
#include<algorithm>
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define pii pair<int,int>
#define pll pair<ll,ll>
#define ll long long
#define fi first
#define se second
#define PB push_back
#define uint unsigned
#define ull unsigned ll
using namespace std;
const int N=1000005;
ll x[N],y[N];
//int f[N][2];
void solve(){
ll X, Y;
int n;
scanf("%lld%lld%d",&X,&Y,&n);
ll dis = 0;
For(i,1,n){
scanf("%lld%lld",&x[i], &y[i]);
ll disx = min(x[i], X - x[i]);
ll disy = min(y[i], Y - y[i]);
dis += min(disx, disy);
}
printf("%lld\n",dis);
}
int main(){
int T;
scanf("%d",&T);
while (T--) solve();
} 需要注意的是题目中坐标范围较大,数据应使用长整型,否则答案错误。 |