NOIP 2014 提高组 复赛 第二天 第一题 无线网路发射器选址 wireless AC代码(二维差分+边界处理)+70代码(二维差分)

NOIP 2014 提高组 复赛 第二天 第一题 无线网路发射器选址 wireless AC代码(二维差分+边界处理)+70代码(二维差分)

总目录详见:NOIP 提高组 复赛 试题 目录 信奥 历年

在线测评地址:[NOIP2014 提高组] 无线网络发射器选址

1.70代码(二维差分)

二维差分不了解,可看下文

差分 一维差分 二维差分 差分数组意义 前缀和 一维前缀和 二维前缀和

 

#include <bits/stdc++.h>
#define LL long long
using namespace std;
LL a[135][135],b[135][135],mx;//b[x][x]表示以(x,y)位置为发射器,所能覆盖的数量
int main(){
	int d,n,x,y,k,i,j,x1,y1,x2,y2,x3,y3,x4,y4,cnt;
	scanf("%d%d",&d,&n);
	for(i=0;i<=128;i++)
		for(j=0;j<=128;j++)
			a[i][j]=0;
	for(i=1;i<=n;i++)
		scanf("%d%d%d",&x,&y,&k),a[x][y]=k;
	for(x=1;x<=128;x++)a[x][0]+=a[x-1][0];//第0行上求和
	for(y=1;y<=128;y++)a[0][y]+=a[0][y-1];//第0列上求和
	for(x=1;x<=128;x++)
		for(y=1;y<=128;y++)
			a[x][y]+=a[x][y-1]+a[x-1][y]-a[x-1][y-1];
	mx=0,cnt=0;
	for(x=0;x<=128;x++)
		for(y=0;y<=128;y++){
			x1=x-d-1,y1=y-d-1;//此处要注意不是x1=x-d,y1=y-d;
			x4=x+d,y4=y+d;
			if(x1<0)x1=0;
			if(y1<0)y1=0;
			if(x4>128)x4=128;
			if(y4>128)y4=128;
			x2=x4,y2=y1;
			x3=x1,y3=y4;
			b[x][y]=a[x4][y4]-a[x2][y2]-a[x3][y3]+a[x1][y1];
			if(mx<b[x][y])mx=b[x][y];
		}
	for(x=0;x<=128;x++)
		for(y=0;y<=128;y++)
			if(b[x][y]==mx)cnt++;
	printf("%d %lld\n",cnt,mx);
	return 0;
}

上述代码70分的原因是,发射器处于道路的边界时,矩阵运算会有问题,具体可看如下测试样例,以下数据为正确数据

INPUT:
1
1
0 0 1

OUTPUT:
4 1

2.AC代码(二维差分+边界处理)

 

在70分代码的基础上,将x坐标整体右移一个单位,将y坐标整体下移一个单位,并做好边界的处理,请仔细比对代码。

#include <bits/stdc++.h>
#define LL long long
using namespace std;
LL a[135][135],b[135][135],mx;//b[x][x]表示以(x,y)位置为发射器,所能覆盖的数量
int main(){
	int d,n,x,y,k,i,j,x1,y1,x2,y2,x3,y3,x4,y4,cnt;
	scanf("%d%d",&d,&n);
	for(i=0;i<=128+1;i++)
		for(j=0;j<=128+1;j++)
			a[i][j]=0;
	for(i=1;i<=n;i++)
		scanf("%d%d%d",&x,&y,&k),a[x+1][y+1]=k;
	for(x=1;x<=128;x++)a[x+1][0+1]+=a[x-1+1][0+1];//第0行上求和
	for(y=1;y<=128;y++)a[0+1][y+1]+=a[0+1][y-1+1];//第0列上求和
	for(x=1;x<=128;x++)
		for(y=1;y<=128;y++)
			a[x+1][y+1]+=a[x+1][y-1+1]+a[x-1+1][y+1]-a[x-1+1][y-1+1];
	mx=0,cnt=0;
	for(x=0+1;x<=128+1;x++)
		for(y=0+1;y<=128+1;y++){
			x1=x-d-1,y1=y-d-1;//此处要注意不是x1=x-d,y1=y-d;
			x4=x+d,y4=y+d;
			if(x1<0)x1=0;
			if(y1<0)y1=0;
			if(x4>128+1)x4=128+1;
			if(y4>128+1)y4=128+1;
			x2=x4,y2=y1;
			x3=x1,y3=y4;
			b[x][y]=a[x4][y4]-a[x2][y2]-a[x3][y3]+a[x1][y1];
			if(mx<b[x][y])mx=b[x][y];
		}
	for(x=0+1;x<=128+1;x++)
		for(y=0+1;y<=128+1;y++)
			if(b[x][y]==mx)cnt++;
	printf("%d %lld\n",cnt,mx);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值