[标程看不懂]导弹实验
【描述】
XX军备公司最近研制成功一种导弹,其爆炸后将圆心为爆炸中心,半径为R(R<=100)的圆形区域内(包括圆周上)的一切物体摧毁。
现在要试验这种导弹的威力。在一个假想的战场(N×M的矩形区域,N,M<=1000)上分布着一些目标。矩阵的坐标原点设定为矩阵的左上角,记为(0,0),每个目标有着不同的价值。同时,该区域还分布着一些一些居民点。没有任何两个建筑(目标或居民点)坐标相同。若未炸毁任何居民点且爆炸范围不超出战场,导弹爆炸的总利益等于所有被炸目标的价值和,否则导弹爆炸的总利益等于0。
现给出假象战场的资料(按先行后列的优先顺序)和导弹的攻击半径r,需要确定导弹的爆炸中心(x0,y0) (x0,y0均为非负整数),使导弹爆炸得到最高总利益。
【输入格式】
输入文件名为missible.in。文件第一行为三个正整数n,m,r,表示矩阵区域的规格和半径。(n,m<=1000,r<=100),接下来,每行有三个整数x,y,V。表示在矩阵区域中坐标值为(X,Y)的方格上有价值为V的建筑,V大于或等于0,小于等于10000。若V=0,则表示该点是一个居民点,文件最后一行为-1 –1 –1,表示文件结束。约定输入文件的大小不超过1M。
【输出格式】
输出文件名为missible.out。文件仅包含一行,若导弹爆炸的总利益等于0,则输出数字0,否则先输出导弹爆炸中心坐标(x0,y0),再输出导弹爆炸后得到的最高总利益。
输入和输出数据之间均用一个空格分开。
【样例输入】
20 20 5
9 2 4
1 3 0
10 4 1
1 7 2
2 9 3
-1 -1 -1
【样例输出】
6 6 8
【分析】
用的是枚举圆心。因为所有的点都是整数,所以用s[j]-s[i-1]表示i~j的值。是一个(n-2r)*(m-2r)*r的算法。
#include <stdio.h>
#include <math.h>
#define maxn 1010
int type[maxn][maxn];
int svalue[maxn][maxn];
int s2[maxn][maxn];
int value[maxn][maxn];
int foud[maxn];
int x,y,z,n,m,r,teans,ans,ansx,ansy,tx,ty;
double sqr(double x)
{
return x*x;
}
bool endf()
{
return ((x==-1)&&(y==-1)&&(z==-1));
}
int main()
{
freopen("missible.in","r",stdin);
freopen("missible.out","w",stdout);
scanf("%d%d%d",&n,&m,&r);
scanf("%d%d%d",&x,&y,&z);
while (!endf())
{
if (z)
{
type[x][y]=1;
value[x][y]=z;
}
else type[x][y]=2;
scanf("%d%d%d",&x,&y,&z);
}
for (int i=0;i<=r;++i) foud[i]=(int)sqrt(sqr(r)-sqr(i));
for (int i=1;i<=n;++i)
for (int j=1;j<=m;++j)
{
svalue[i][j]=svalue[i][j-1]+value[i][j];
s2[i][j]=s2[i][j-1];
if (type[i][j]==2) ++s2[i][j];
}
int i,j,k;
for (j=r;j<=m-r;++j)
for (i=r;i<=n-r;++i)
{
teans=0;
for (k=0;k<=r;++k)
{
tx=i+k;
if (s2[tx][j+foud[k]]-s2[tx][j-foud[k]-1]>0)
{
teans=-1;
break;
}
else teans+=svalue[tx][j+foud[k]]-svalue[tx][j-foud[k]-1];
if (k)
{
tx=i-k;
if (s2[tx][j+foud[k]]-s2[tx][j-foud[k]-1]>0)
{
teans=-1;
break;
}
else teans+=svalue[tx][j+foud[k]]-svalue[tx][j-foud[k]-1];
}
}
if (teans>ans)
{
ans=teans;
ansx=i;
ansy=j;
}
}
if (ans) printf("%d %d %d\n",ansx,ansy,ans);
else printf("0\n");
return 0;
}
浙公网安备 33010602011771号