Luogu1861 星之器

Description

link

现在有一个 n×m 的矩阵A,里面的每个元素ai,j 表示二元组(i,j)的位置有ai,j 颗星星

现在我们有一种操作,选定同一行或同一列的两个星组 a ,把他们中的一颗星星向中间移动一个单位,该操作的贡献是两个位置的曼哈顿距离(意会一下,相当简单)

给定初始矩阵 A, 和末尾矩阵 B,保证 B 是由 A 进行一定的上述操作得到,求贡献和

Solution

单看题目一脸懵逼……

直接上思路吧:(真的是闻所未闻的人类智慧)

定义一颗位于的二元组(i,j)的星星的 “势能”i2+j22

我们考虑每一个移动对于两个位置的星星的势能的影响

E0=x12+y12+x22+y222

E=(x1+1)2+y12+(x21)2+y222

ΔE=x2  x1

我们要的贡献就是ΔE

然后我们发现这个移动跟操作的方式是无关的!!!!

所以这个题就做完了

ans=i=1nj=1mai,j(i2+j2)2i=1nj=1mbi,j(i2+j2)2

可以乘法分配律一下啥的

Code

#include<bits/stdc++.h>
using namespace std;
#define int long long
namespace yspm{
	inline int read()
	{
		int res=0,f=1; char k;
		while(!isdigit(k=getchar())) if(k=='-') f=-1;
		while(isdigit(k)) res=res*10+k-'0',k=getchar();
		return res*f;
	}
	const int N=210;
	int a[N][N],b[N][N],n,ans,m;
	signed main()
	{
		n=read(); m=read(); 
		for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) a[i][j]=read(); 
		for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) b[i][j]=read();
		for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) ans+=(a[i][j]-b[i][j])*(i*i+j*j); 
		printf("%lld\n",ans>>1);
		return 0;
	}
}
signed main(){return yspm::main();}
posted @   没学完四大礼包不改名  阅读(173)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示