列表

详情


NC19811. Matrix

描述

弱弱有一个n x m的矩阵,第i行第j列位置上的值为aij
弱弱定义以(x, y)为顶点,大小为k的三角形为:
第x行y位置,
第x+1行y-1,y,y+1位置,

第x+k-1行y-k+1,,y+k-1位置
组成的区域。
比如说,以(1,3)为顶点,大小为3的三角形为

OOXOOOO
OXXXOOO
XXXXXOO
OOOOOOO
中打叉的位置。
现在弱弱想要知道所有大小为k的三角形中,重心位置离顶点最近的是哪个?重心是三角形中每个位置按照它们的值加权平均所得的点。
请输出这个最小距离(欧几里得距离)。

输入描述

第一行一个三个整数n,m,k(1≤ n ≤ 1000,1≤ m≤ 1000,1 ≤ k ≤ min(n, (m + 1) / 2)。
接下来n行,每行m个整数aij(1≤ aij≤ 1000)表示每个位置的重量。

输出描述

一行一个数表示答案。相对误差或绝对误差在10-5(1e-5)之内均会被判断为正确。

示例1

输入:

2 3 2
1 1 1
1 1 1

输出:

0.7500000000

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 330ms, 内存消耗: 63088K, 提交时间: 2018-10-06 15:13:22

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
const int MAXN = 1000 + 10;


int n, m, k;
int w[MAXN][MAXN];
int wx[MAXN][MAXN], wy[MAXN][MAXN];
long long valx[MAXN][MAXN], valy[MAXN][MAXN], totw[MAXN][MAXN];
typedef long long LL;
void solve(int a[MAXN][MAXN], LL ans[MAXN][MAXN]) {
  static LL sumv[MAXN << 1][MAXN], sumw[MAXN << 1][MAXN];
  const LL O = 1e3;
  
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      sumv[i + j][j] = sumv[i + j][j + 1] + a[i][j];
      sumw[i - j + O][j] = sumw[i - j + O][j - 1] + a[i][j];
    }
  }

  for (int i = k; i <= n; i++) {
    LL tot = 0;
    for (int j = 1; j <= k; j++) {
      tot += sumv[i + j][j] - sumv[i + j][k + 1];
    }
    for (int j = k + 1; j <= 2 * k - 1; j++) {
      tot += sumw[i - j + O][j] - sumw[i - j + O][k];
    }
    ans[i][k] = tot;

    for (int j = k + 1; j <= m - k + 1; j++) {
      tot -= sumv[i + (j - k)][j - k] - sumv[i + (j - k)][j];
      tot += sumw[i - (j + k - 1) + O][j + k - 1] - sumw[i - (j + k - 1) + O][j - 1];
      ans[i][j] = tot;
    }
  }
    
}
double sqr(double x) { return x * x; }
int main() {
  scanf("%d%d%d", &n, &m, &k);
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      scanf("%d", &w[i][j]);
      wx[i][j] = w[i][j] * i;
      wy[i][j] = w[i][j] * j;
    }
  }

  solve(wx, valx);
  solve(wy, valy);
  solve(w, totw);

  double ans = 1e30;
  for (int i = k; i <= n; i++) {
    for (int j = k; j <= m - k + 1; j++) {
      double ansx = 1.0 * valx[i][j] / totw[i][j];
      double ansy = 1.0 * valy[i][j] / totw[i][j];
      //fprintf(stderr, "%.10f\n", sqr(ansx - (i - k + 1)) +
      //        sqr(ansy - j));
      
      ans = std::min(ans, sqr(ansx - (i - k + 1)) +
                     sqr(ansy - j));
    }
  }

  printf("%.10f\n", sqrt(ans));



}

C++11(clang++ 3.9) 解法, 执行用时: 237ms, 内存消耗: 98668K, 提交时间: 2018-10-06 14:00:16

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1010;
int a[N][N],n,m,k;
ll xa1[N][N],ya1[N][N],za1[N][N];//横行前缀和
ll xa2[N][N],ya2[N][N],za2[N][N];//左斜行前缀和
ll xa3[N][N],ya3[N][N],za3[N][N];//右斜行前缀和
ll ansx[N][N],ansy[N][N],ansz[N][N];
double ans=1e9,avex,avey;

int main(){
	scanf("%d%d%d",&n,&m,&k);
	for(int i=1; i<=n; i++){
		for(int j=1; j<=m; j++){
			scanf("%d",&a[i][j]);
			xa1[i][j]=xa1[i][j-1]+i*a[i][j];
			ya1[i][j]=ya1[i][j-1]+j*a[i][j];
			za1[i][j]=za1[i][j-1]+a[i][j];

			xa2[i][j]=xa2[i-1][j+1]+i*a[i][j];
			ya2[i][j]=ya2[i-1][j+1]+j*a[i][j];
			za2[i][j]=za2[i-1][j+1]+a[i][j];

			xa3[i][j]=xa3[i-1][j-1]+i*a[i][j];
			ya3[i][j]=ya3[i-1][j-1]+j*a[i][j];
			za3[i][j]=za3[i-1][j-1]+a[i][j];
		}
	}
	for(int i=1; i+k-1<=n; i++){
		for(int ii=0; ii<k; ii++){
			ansx[i][k]+=xa1[i+ii][k+ii]-xa1[i+ii][k-ii-1];
			ansy[i][k]+=ya1[i+ii][k+ii]-ya1[i+ii][k-ii-1];
			ansz[i][k]+=za1[i+ii][k+ii]-za1[i+ii][k-ii-1];
		}
		for(int j=k+1; j+k-1<=m; j++){
			ansx[i][j]=ansx[i][j-1];
			ansy[i][j]=ansy[i][j-1];
			ansz[i][j]=ansz[i][j-1];

			ansx[i][j]-=xa2[i+k-1][j-k]-xa2[i-1][j];
			ansy[i][j]-=ya2[i+k-1][j-k]-ya2[i-1][j];
			ansz[i][j]-=za2[i+k-1][j-k]-za2[i-1][j];

			ansx[i][j]+=xa3[i+k-1][j+k-1]-xa3[i-1][j-1];
			ansy[i][j]+=ya3[i+k-1][j+k-1]-ya3[i-1][j-1];
			ansz[i][j]+=za3[i+k-1][j+k-1]-za3[i-1][j-1];
		}
		for(int j=k; j+k-1<=m; j++){
			//cout<<i<<" "<<j<<" :"<<ansx[i][j]<<" "<<ansy[i][j]<<" "<<ansz[i][j]<<endl;
			avex=1.0*ansx[i][j]/(1.0*ansz[i][j])-1.0*i;
			avey=1.0*ansy[i][j]/(1.0*ansz[i][j])-1.0*j;
			//printf("%.10lf %.10lf\n",avex,avey);
			ans=min(ans,avex*avex+avey*avey);
		}
	}
	printf("%.10lf\n",pow(ans,0.5));
	return 0;
}

上一题