• 现哥的兰博基尼(枚举)


    现哥的兰博基尼(rich.pas/c/cpp)
    Time Limit:1s Memory Limit:256MB
    【题目描述】
    现哥准备现在从没钱开始攒钱买辆兰博基尼!1秒……2秒……3秒……好吧,攒够了!
    现哥附近的广场正好有家兰博基尼的车展会。这个展会由多个4×4的平台组成。每个平台的中心都有一辆兰博基尼。但是很不科学的是这里有N行M列平台,也就意味着有N×M辆兰博基尼,而兰博基尼是全球限量发售的,一次出现如此多的兰博基尼说明其中大部分都是冒牌货!而冒牌货中有高端的,也有低端的,而冒牌货的高端低端可以表示成冒牌指数k,k越大意味着这个冒牌货越高端。而k达到一定大小时就是正品了。现哥一眼就看出了所有N*M辆兰博基尼的k值,但是他想找一个地方,站在那里,仔细研究每辆兰博基尼。如果将整个展台看作平面直角坐标系,4×4平台的边界平行于坐标轴。以左下角平台的左下角端点作为原点,那么展台的图如下图所示:

    上图每个正方形的中央都有辆兰博基尼。
    假定现哥所在坐标(x1,y1),现哥所观察的兰博基尼的坐标为(x2,y2),冒牌指数为k,那么现哥观察这辆兰博基尼所花时间为k*((x1-x2)2+(y1-y2)2),而现哥希望找到一个位置(x,y)使得他观察所有兰博基尼的所需要的总时间最少。特别的,由于现哥想站在4×4平台的端点上,所以他要求他所在的横纵坐标值必须都能被4整除!

    【输入格式】
    第一行两个数字N,M,表示车展会的规模。
    接下来N行,每行M个数字,即第N行M列平台中的兰博基尼的k值。

    【输出格式】
    输出一行,即现哥观察所有兰博基尼的最小耗时。

    【样例输入输出】
    rich.in rich.out
    2 3
    3 4 5
    3 9 1 392

    【样例解释】
    当现哥站在坐标(4,4)上时,观察第一行兰博基尼的耗时分别为:24、32、200。
    观察第二行兰博基尼的耗时分别为:24、72、40
    总时间为392

    【数据范围】
    30%的数据:1≤N,M≤50。
    100%的数据:1≤N,M≤1000,0≤k≤10^5。
    【解题报告】
    考试的时候只想到暴力,复杂度为O(n^4) 预期得分30分
    我们其实可以化简式子
    ({sumlimits_{i=1}^{n}sumlimits_{j=1}^{m}Kij*((x-xi)^2+(y-yj)^2) })
    =({sumlimits_{i=1}^{n}sumlimits_{j=1}^{m}Kij*(x-xi)^2 }) + ({sumlimits_{i=1}^{n}sumlimits_{j=1}^{m}Kij*(y-yj)^2 })
    =({sumlimits_{i=1}^{n}(x-xi)^2sumlimits_{j=1}^{n}Kij }) + ({sumlimits_{j=1}^{m}(y-yj)^2sumlimits_{i=1}^{n}Kij })
    对于这两个式子,我们可以预处理把({sumlimits_{i=1}^{n}Kij})({sumlimits_{j=1}^{m}Kij})求出来,这样,我们只要单独枚举x与y就可以。
    预处理O(mn)
    枚举O(m2+n2)
    注意要开long long!

    #include <iostream>
    #include <cmath>
    #include <queue>
    #include <algorithm>
    #include <cstring>
    #include <climits>
    #define MAXN 1000+10
    #define MAX LONG_LONG_MAX
    using namespace std;
    int n,m;
    long long g[MAXN][MAXN],gi[MAXN],gj[MAXN];
    long long ans=MAX,minx=MAX,miny=MAX;
    int main()
    {
    	freopen("rich.in","r",stdin);
    	freopen("rich.out","w",stdout);
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++)
    			scanf("%d",&g[i][j]);
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++)
    			gi[i]+=g[i][j];
    	for(int j=1;j<=m;j++)
    		for(int i=1;i<=n;i++)
    			gj[j]+=g[i][j];
    	for(int x=0;x<=4*n;x+=4)
    	{
    		long long temp=0;
    		for(int i=2;i<=4*n;i+=4)
    			temp+=1LL*(x-i)*(x-i)*gi[int((i+2)/4.0)];
    		if(minx>temp) minx=temp;
    	}
    	for(int y=0;y<=4*n;y+=4)
    	{
    		long long temp=0;
    		for(int j=2;j<=4*m;j+=4)
    			temp+=1LL*(y-j)*(y-j)*gj[int((j+2)/4.0)];
    		if(miny>temp) miny=temp;
    	}
    	ans=minx+miny;
    	printf("%lld
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    C语言I博客作业08
    C语言I博客作业07
    C语言I博客作业06
    C语言I博客作业05
    C语言I博客作业04
    String详解
    数据库中索引相关基础知识
    论文笔记:RankIQA
    目标检测 | 火焰烟雾检测论文(实验部分)
    图像质量评价:合成失真图像方法
  • 原文地址:https://www.cnblogs.com/yangyaojia/p/6370499.html
Copyright © 2020-2023  润新知