牛客 - 仓库选址(中位数+思维)

题目链接:点击查看

题目大意:给出一个 n * m 的矩阵,每个格子中都有一个数字,代表需要运货的次数,现在需要选出一个点作为仓库,使得累计运货的路程最短

题目分析:真没想到数据水到能让 n^4 的算法水过去,多的就不说了,一会会挂暴力的头铁代码的

重点想说一下如何用中位数解决这个问题,关于中位数处理类似的一维问题,我们只需要求出 x 轴上的中位数,选取该位置作为仓库肯定是最优的了,那么在二维平面该如何选择呢,其实也是同理,我们只需要沿着行开始遍历,确定下来 x 的坐标,然后再沿着列开始遍历,确定下来 y 的坐标,这样就可以确定下来仓库的具体位置,剩下的 n^2 计算出答案就好了

代码:

中位数:

#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
using namespace std;
     
typedef long long LL;
    
typedef unsigned long long ull;
     
const int inf=0x3f3f3f3f;

const int N=110;

LL a[N][N];

int main()
{
#ifndef ONLINE_JUDGE
//    freopen("input.txt","r",stdin);
//    freopen("output.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);
   	int w;
   	cin>>w;
   	while(w--)
   	{
   		int n,m;
   		scanf("%d%d",&m,&n);
   		LL sum=0;
   		for(int i=1;i<=n;i++)
   			for(int j=1;j<=m;j++)
   			{
   				scanf("%lld",&a[i][j]);
   				sum+=a[i][j];
			}
		int x,y;
		LL mid=sum+1>>1;
		LL now=0;
   		for(int i=1;i<=n;i++)
   		{
   			for(int j=1;j<=m;j++)
   				now+=a[i][j];
			if(now>=mid)
   			{
   				x=i;
   				break;
			}
		}
		now=0;
		for(int j=1;j<=m;j++)
		{
			for(int i=1;i<=n;i++)
				now+=a[i][j];
			if(now>=mid)
			{
				y=j;
				break;
			}
		}
		LL ans=0;
		for(int i=1;i<=n;i++)
			for(int j=1;j<=m;j++)
				ans+=a[i][j]*(abs(i-x)+abs(j-y));
		printf("%lld\n",ans);
	}
   	
   	
   	
    
    
    
    
    
    
    
    
    
    
    
    
    
    return 0;
}

暴力:

#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
using namespace std;
      
typedef long long LL;
     
typedef unsigned long long ull;
      
const int inf=0x3f3f3f3f;
 
const int N=110;
 
LL a[N][N];
 
int main()
{
#ifndef ONLINE_JUDGE
//    freopen("input.txt","r",stdin);
//    freopen("output.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);
    int w;
    cin>>w;
    while(w--)
    {
        int n,m;
        scanf("%d%d",&m,&n);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                scanf("%lld",&a[i][j]);
        LL ans=1e18;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                LL temp=0;
                for(int ii=1;ii<=n;ii++)
                    for(int jj=1;jj<=m;jj++)
                        temp+=a[ii][jj]*(abs(i-ii)+abs(j-jj));
                ans=min(ans,temp);
            }
        printf("%lld\n",ans);
    }
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    return 0;
}
发布了655 篇原创文章 · 获赞 21 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_45458915/article/details/104453737