G-仓库选址_牛客小白月赛22 (nowcoder.com)https://ac.nowcoder.com/acm/contest/4462/G
据出题人分析:“简要题意是找到一个位置,使得其它所有位置上的数乘以两个位置之间的距离的总和最小。直接暴力枚举每一个位置然后取一个最小值即可。”
第一种方法因为数据范围非常小,所以直接暴力枚举每一个位置作为起点。
时间复杂度O(n*n*m*m);
int main()
{
#ifdef JANGYI
freopen("input.txt", "r", stdin);
freopen("output.out", "w", stdout);
#endif
IOS;
int t;
cin >> t;
while (t--)
{
int n, m;
cin >> m >> n;
int a[105][105];
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> a[i][j];
int ans = inf;
for (int x = 1; x <= n; x++)
{
for (int y = 1; y <= m; y++)
{
int sum = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
sum += a[i][j] * (abs(x - i) + abs(y - j));
ans = min(ans, sum);
}
}
cout << ans << endl;
}
return 0;
}
第二种方法:
我们思考一下,其实在暴力做法中每次枚举每个位置都要再算一次所有的距离,其实这是完全没有必要的。假设当前仓库位置(x, y),如果向下移一位到(x + 1, y),那么以(1, 1)为左上角,
(n, y)为右下角的矩阵中的所有商店到仓库的距离会加1,以(1, y + 1)为左上角,(n, m)为右下角的矩阵的距离都会减一,那么我们就可以先让仓库放在(1, 1)位置,不断移动更新最小值,时间复杂度O(n*m)
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
#include<map>
using namespace std;
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define lowbit(x) x & -x
#define inf 0x3f3f3f3f
#define se second
#define fi first
#define endl '\n'
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pii;
int read() {
int x = 0, f = 1;
char c = getchar();
while (c < '0' || c>'9') { if (c == '-') f = -1; c = getchar(); }
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
const int N = 100010, mod = 998244353;
int sum[105][105];
int get(int a, int b, int c, int d)
{
return sum[c][d] - sum[a - 1][d] - sum[c][b - 1] + sum[a - 1][b - 1];
}
int main()
{
#ifdef JANGYI
freopen("input.txt", "r", stdin);
freopen("output.out", "w", stdout);
#endif
IOS;
int t;
cin >> t;
while (t--)
{
int n, m;
cin >> m >> n;
int a[105][105];
int now = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
{
int x; cin >> x;
now += ((i - 1) + (j - 1)) * x;
sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sun[i - 1][j - 1] + x;
}
int ans = inf;
for (int i = 1; i <= n; i++)
{
int p = now;
for (int j = 1; j <= m; j++)
{
ans = min(ans, p);
p = p + get(1, 1, n, j) - get(1, j + 1, n, m);
}
now = now + get(1, 1, i, m) - get(i + 1, 1, n, m);
}
cout << ans << endl;
}
return 0;
}