Description
给定一个矩阵,定义一个操作:
选择两个同一行或同一列不相邻的点,将这两个点上各一个星向中间移动一位,产生魔力为两点间距离-1,求始态到终态的产生魔力
n,m<=200,Ai,j<=1000
分析
我们对每个格子 (i,j) 定义一个势为 i∗i+j∗j ,假设现在选择了两个点 (i,j) 和 (i,k) 且 j+2<=k
那么操作前的势为:
i∗i+j∗j+i∗i+k∗k
操作之后的势为:
i∗i+(j+1)∗(j+1)+i∗i+(k−1)∗(k−1)
前减后得:
2∗k−2∗j−2=2∗(k−j−1)
那么我们就可以发现,答案就是初始的势-结束的势
代码
#include <bits/stdc++.h>
#define ll long long
int read()
{
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
return x * f;
}
int main()
{
ll ans = 0;
int n = read(), m = read();
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
{
int x = read();
ans += x * (i * i + j * j);
}
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
{
int x = read();
ans -= x * (i * i + j * j);
}
printf("%lld\n", ans / 2);
}