hiho 编程之美2015资格赛(基站选址-绝对值方程分段)[WA]

本文介绍了一个通讯基站选址问题的优化算法。目标是在限定的网格内找到最佳位置建立基站,以最小化用户到基站的距离成本及基站维护成本。通过数学方法求解最优解,并提供了具体的实现代码。

题目3 : 基站选址

时间限制:2000ms
单点时限:1000ms
内存限制:256MB

描述

需要在一个N × M的网格中建立一个通讯基站,通讯基站仅必须建立在格点上。

网格中有A个用户,每个用户的通讯代价是用户到基站欧几里得距离的平方。

网格中还有B个通讯公司,维护基站的代价是基站到最近的一个通讯公司的路程(路程定义为曼哈顿距离)。

在网格中建立基站的总代价是用户通讯代价的总和加上维护基站的代价,最小总代价。

输入

第一行为一个整数T,表示数据组数。

每组数据第一行为四个整数:N, M, A, B。

接下来的A+B行每行两个整数x, y,代表一个坐标,前A行表示各用户的坐标,后B行表示各通讯公司的坐标。

输出

对于每组数据输出一行"Case #X: Y",X代表数据编号(从1开始),Y代表所求最小代价。

数据范围

1 ≤ T ≤ 20

1 ≤ x ≤ N

1 ≤ y ≤ M

1 ≤ B ≤ 100

小数据

1 ≤ N, M ≤ 100

1 ≤ A ≤ 100

大数据

1 ≤ N, M ≤ 107

1 ≤ A ≤ 1000

样例输入
2
3 3 4 1
1 2
2 1
2 3
3 2
2 2
4 4 4 2
1 2
2 4
3 1
4 3
1 4
1 3
样例输出
Case #1: 4
Case #2: 13

x,y可以单独考虑,∑(X-xi)^2+|x-a| 在[1,n]整数范围内最小值,解方程即可


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  
#define Lson (x<<1)
#define Rson ((x<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define MAXN (10000000+10)
#define MAXA (1000+10)
typedef long long ll;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int T;
int n,m,A,B;
ll _x[MAXN],_y[MAXN];

ll a2[MAXN],b2[MAXN];
ll f(ll a,ll b,ll c,ll x){return a*x*x+b*x+c;}
ll calc(int i,ll _x[],ll a2[],ll n)
{
	
	ll a=A,b=0,c=0;
	For(i,A) b+=-2*_x[i],c+=_x[i]*_x[i];
	b+=1;c-=a2[i];		
	double x= (double)((double)(-b)/double(2*a));
	ll X1=floor(x),X2=ceil(x);
	
	ll ans1 = f(a,b,c,a2[i]);
	if (0<=X1&&X1<=n&&X1>a2[i]) ans1=min(ans1,f(a,b,c,X1));
	if (0<=X2&&X2<=n&&X2>a2[i]) ans1=min(ans1,f(a,b,c,X2));
	if (0>a2[i]) ans1=min(ans1,f(a,b,c,0));
	if (n>a2[i]) ans1=min(ans1,f(a,b,c,n));
	
	a=A,b=0,c=0;
	For(i,A) b+=-2*_x[i],c+=_x[i]*_x[i];
	b-=1;c+=a2[i];		
	x= (double)((double)(-b)/double(2*a));
	X1=floor(x),X2=ceil(x);
	
	if (0<=X1&&X1<=n&&X1<a2[i]) ans1=min(ans1,f(a,b,c,X1));
	if (0<=X2&&X2<=n&&X2<a2[i]) ans1=min(ans1,f(a,b,c,X2));
	if (0<a2[i]) ans1=min(ans1,f(a,b,c,0));
	if (n<a2[i]) ans1=min(ans1,f(a,b,c,n));
	
	
	
	return ans1;
	
/*	a=n,b=0,c=0;
	For(i,n) b+=-2*_y[i],c+=_y[i]*_y[i];
	ll Y= floor((double)(-2*a)/double(b));
	return ans;	
*/
}
int main()
{
//	freopen("base.in","r",stdin);
	
	scanf("%d",&T);
	For(kcase,T)
	{
		scanf("%d%d%d%d",&n,&m,&A,&B);
		
		For(i,A)
		{
			scanf("%lld%lld",&_x[i],&_y[i]);
		}
		
		
		int ans=-1;
		For(i,B)
		{
			scanf("%lld%lld",&a2[i],&b2[i]);
			int p=calc(i,_x,a2,n)+calc(i,_y,b2,m);
			if (ans==-1||p<ans) ans=p;
		}
		
		
		
		printf("Case #%d: %lld\n",kcase,ans);
	}
	 
	
	
	
	return 0;
}





源码地址: https://pan.quark.cn/s/d1f41682e390 miyoubiAuto 米游社每日米游币自动化Python脚本(务必使用Python3) 8更新:更换cookie的获取地址 注意:禁止在B站、贴吧、或各大论坛大肆传播! 作者已退游,项目不维护了。 如果有能力的可以pr修复。 小引一波 推荐关注几个非常可爱有趣的女孩! 欢迎B站搜索: @嘉然今天吃什么 @向晚大魔王 @乃琳Queen @贝拉kira 第三方库 食用方法 下载源码 在Global.py中设置米游社Cookie 运行myb.py 本地第一次运行时会自动生产一个文件储存cookie,请勿删除 当前仅支持单个账号! 获取Cookie方法 浏览器无痕模式打开 http://user.mihoyo.com/ ,登录账号 按,打开,找到并点击 按刷新页面,按下图复制 Cookie: How to get mys cookie 当触发时,可尝试按关闭,然后再次刷新页面,最后复制 Cookie。 也可以使用另一种方法: 复制代码 浏览器无痕模式打开 http://user.mihoyo.com/ ,登录账号 按,打开,找到并点击 控制台粘贴代码并运行,获得类似的输出信息 部分即为所需复制的 Cookie,点击确定复制 部署方法--腾讯云函数版(推荐! ) 下载项目源码和压缩包 进入项目文件夹打开命令行执行以下命令 xxxxxxx为通过上面方式或取得米游社cookie 一定要用双引号包裹!! 例如: png 复制返回内容(包括括号) 例如: QQ截图20210505031552.png 登录腾讯云函数官网 选择函数服务-新建-自定义创建 函数名称随意-地区随意-运行环境Python3....
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值