2021.8.12提高B组模拟4T3 矩阵(小根堆)(map判重)

Posted SSL_LKJ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021.8.12提高B组模拟4T3 矩阵(小根堆)(map判重)相关的知识,希望对你有一定的参考价值。

矩阵

题目大意

输入样例

1.

3 4 2 2 3
0 1 3 7
1 16 5 2
7 6 9 3

2.

7 7 3 4 13
5 5 7 8 6 8 5
8 4 6 6 3 4 2
8 0 9 2 3 4 7
8 5 4 5 3 9 8
0 3 0 6 0 3 8
9 7 1 8 8 9 4
7 8 4 5 7 6 1

输出样例

1.

19

2.

58

题目数据

解题思路

首先区间求和就不用多说了——二维前缀和

矩阵的权值肯定 > = >= >=其子矩阵的权值

所以一个小根堆

所有长为 m i n a mina mina ,宽为 m i n b minb minb 的和谐矩阵加入堆

重复 k k k 次这样的操作

1.每次从堆中取出权值最小的和谐矩阵,同时扩展出2个新的权值(即新扩展一个列和行)

2.判重(可以用 m a p map map 或者 h a s h hash hash

最后答案就是堆顶

AC代码

#include<iostream>
#include<cstdio>
#include<queue>
#include<map>
using namespace std;
int n,m,mina,minb,k,tot;
long long a[1005][1005];
struct node//小根堆的结构体
{
	int x1,y1,x2,y2;
	long long sum;
	bool operator<(const node&x)const
	{
		return sum>x.sum;
	}
};
long long getsum(int x,int y,int i,int j)//求出区间和
{
	return a[i][j]-a[x][j]-a[i][y]+a[x][y];
}
int getnum(int x,int y)//二维坐标的一维编号
{
	return (x-1)*m+y;
}
priority_queue<node>q;
map<pair<int,int>,int>ha;
int main()
{
	scanf("%d%d%d%d%d",&n,&m,&mina,&minb,&k);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
			int x;
			scanf("%d",&x);
			a[i][j]=a[i-1][j]+a[i][j-1]-a[i-1][j-1]+x;
		}
	for(int i=1;mina+i-1<=n;i++)//先放长、宽最小的和谐矩阵
		for(int j=1;minb+j-1<=m;j++)
			q.push((node){i,j,mina+i-1,minb+j-1,getsum(i-1,j-1,mina+i-1,minb+j-1)});
	for(int i=1;i<k;i++)//重复k-1次
	{
		if(q.empty())//判断是否为空
		{
			printf("-1");
			return 0;
		}
		node x=q.top();//队首
		q.pop();//弹出队首
		//下面是两种情况分类讨论
		if(x.x2+1<=n)//判断是否越界
			if(!ha[make_pair(getnum(x.x1,x.y1),getnum(x.x2+1,x.y2))])//判重
				ha[make_pair(getnum(x.x1,x.y1),getnum(x.x2+1,x.y2))]=1,
				q.push((node){x.x1,x.y1,x.x2+1,x.y2,getsum(x.x1-1,x.y1-1,x.x2+1,x.y2)});//放入堆中
		if(x.y2+1<=m)
			if(!ha[make_pair(getnum(x.x1,x.y1),getnum(x.x2,x.y2+1))])
				ha[make_pair(getnum(x.x1,x.y1),getnum(x.x2,x.y2+1))]=1,
				q.push((node){x.x1,x.y1,x.x2,x.y2+1,getsum(x.x1-1,x.y1-1,x.x2,x.y2+1)});
	}
	if(q.empty())//判断是否为空
	{
		printf("-1");
		return 0;
	}
	printf("%lld",q.top().sum);
	return 0;
}

谢谢

以上是关于2021.8.12提高B组模拟4T3 矩阵(小根堆)(map判重)的主要内容,如果未能解决你的问题,请参考以下文章

2021.8.13提高B组模拟5T2 Crisis(小根堆)

2021.8.13提高B组模拟5T2 Crisis(小根堆)

2021.7.15提高B组模拟4T3 鱼跃龙门(exgcd)

2021.8.12提高B组模拟4T1 幻象(期望dp)

2021.8.12提高B组模拟4T2 树上摩托(bfs)

2021.8.12提高B组模拟4T1 幻象(期望dp)