CF 201B Guess That Car!

本文介绍了一种计算点到多个方块距离的优化方法,并通过具体的示例解释了如何利用行列特性简化距离计算公式。该方法有助于减少计算复杂度,提高算法效率。

公式拆分。

一个点 到每个方块的Distance可以拆分为:dx^2 + dy^2;

第一个example~:

(1,1) : c[1][1]*dx[1][1] + c[1][1]*dy[1][1] +

    c[1][2]*dx[1][2] + c[1][2]*dy[1][2] +   

          c[1][3]*dx[1][3] + c[1][3]*dy[1][3] +

    c[2][1]*dx[2][1] + c[2][1]*dy[2][1] +              因为dy[1][1] = dy[1][2] = dy[1][3] = dy[1] 

    c[2][2]*dx[2][2] + c[2][2]*dy[2][2] +                      dy[2][1] = dy[2][2] = dy[2][3] = dy[2] 

    c[2][3]*dx[2][3] + c[2][3]*dy[2][3] ;                       dx[1][1] = dx[2][1] = dx[1]  dx[1][2] = dx[2][2] = dx[2]  dx[1][3] = dx[2][3] = dx[3];

  可以看出每个行dy一样,每列的dx一样

抽象下表达式就可以了~

我的代码比较恶心:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <algorithm>
#include <vector>
#include <limits.h>
#include <queue>
#include <stack>
#include <map>
#define LL long long
using namespace std;
LL mp[1010][1010];
LL mpx[1010],mpy[1010];
int main()
{
    LL n,m;
    while(scanf("%I64d%I64d",&n,&m)!=EOF)
    {
        memset(mp,0,sizeof(mp));
        for(LL i = 0;i < n;i ++)
            for(LL j = 0;j < m;j ++)
            scanf("%I64d",&mp[i][j]);
        for(LL i = 0;i < n;i ++){
            for(LL j = 0;j < m;j ++)
            {
                mp[i][m] += mp[i][j];
                mp[n][j] += mp[i][j];
            }
        }
        for(LL i = 0;i <= n;i ++)
        {
            LL sum = 0;
            LL k = 0;
            for(LL j = 0;j <= n;j ++)
            {
                if(i == j) continue;
                sum += ((abs(i-j)-0.5)*4*(abs(i-j)-0.5)*4*mp[k++][m]);
            }
            mpx[i] = sum;
            //if(sum < mix) mix = sum;
        }
        for(LL i = 0;i <= m;i ++)
        {
            LL sum = 0;
            LL k = 0;
            for(LL j = 0;j <= m;j ++)
            {
                if(i == j) continue;
                sum += ((abs(i-j)-0.5)*4*(abs(i-j)-0.5)*4*mp[n][k++]);
            }
            mpy[i] = sum;
            //if(sum < miy) miy = sum;
        }
        LL mi = LONG_LONG_MAX,mx,my;
        for(LL i = 0;i <= n;i ++)
        {

            for(LL j = 0;j <= m;j ++)
            {
                if(mpx[i]+ mpy[j] < mi) {
                    mi = mpx[i] + mpy[j];
                    mx = i;my = j;
                }
            }
        }
        printf("%I64d\n%I64d %I64d\n",mi,mx,my);



    }
}


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值