2018 “百度之星”程序设计大赛 - 初赛(B) rect

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 * 0 * 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
#include
#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
#define pll pair
#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();
}

需要注意的是题目中坐标范围较大,数据应使用长整型,否则答案错误。

你可能感兴趣的:(C++)