1578: 自习教室
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 261 Solved: 26
[Submit][Status][Web Board]
Description
快期末了,小明要开始预习课本了,作为一名爱玩的学渣,他需要找一个相对最安静的位置来学习,然而图书馆还是会有一些人不安分的发出噪音,现在给出一张n*m的矩阵来表示图书馆的状态。如果这个点是0则表示这个对应的位置为空,如果不是0则表示这里有个会发出噪音系数为a的人存在,噪音是会随着距离的增加而降低的,降低的幅度等于距离,两个点的距离用|x1-x2|+|y1-y2|表示
Input
多组测试数据
第一行包含两个数字n和m和k(0<n,m<100,0<=k<=n*m)表示图书馆的长和宽
接下来k行,每行三个数字i,j,s(0<=i<n,0<=j<m,0<s<10)表示噪音源的坐标以及噪音系数
Output
输出最安静的位置i,j(表示i行j列)以及受到的噪音指数是多少,如果有多个答案输出i最小的,若i一样输出j最小的
Sample Input
3 3 1 1 1 3
Sample Output
0 0 1
HINT
Source
【解题思路】
因为直接做是会超时的,所以考虑到对于声源(x,y)在x轴方向和y轴方向只有距离(x,y)1到s-1的距离才有可能受到影响,所以先预处理一下x轴和y轴方向,至于其他方向也是同理,因为题目中说噪音是会随着距离的增加而降低的,降低的幅度等于距离,两个点的距离用|x1-x2|+|y1-y2|表示,其实就已经将这个绝对值表达式化简成了i+j,所以只要i+j<s则说明这个地方是会受声源影响的,最后更新一下最小值即可。
【代码】
#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=105;
int a[maxn][maxn];
int main()
{
int n,m,k;
while(~scanf("%d%d%d",&n,&m,&k))
{
memset(a,0,sizeof(a));
while(k--)
{
int x,y,s;
scanf("%d%d%d",&x,&y,&s);
a[x][y]+=s;
for(int i=1;i<s;i++)
{
if(x-i>=0)a[x-i][y]+=s-i;
if(x+i<n)a[x+i][y]+=s-i;
if(y-i>=0)a[x][y-i]+=s-i;
if(y+i<m)a[x][y+i]+=s-i;
}
for(int i=1;i<s;i++)
{
for(int j=1;j<s;j++)
{
if(i+j<s)
{
if(x-i>=0 && y-j>=0)a[x-i][y-j]+=s-i-j;
if(x+i<n && y+j<m)a[x+i][y+j]+=s-i-j;
if(x-i>=0 && y+j<m)a[x-i][y+j]+=s-i-j;
if(x+i<n && y-j>=0)a[x+i][y-j]+=s-i-j;
}
}
}
}
int ans=INF,ansi=0,ansj=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(a[i][j]<ans)
{
ans=a[i][j];
ansi=i;
ansj=j;
}
}
}
printf("%d %d %d\n",ansi,ansj,ans);
}
return 0;
}