Checksum-Google Kick Start 2021 Round A

在Google Kick Start 2021 Round A中,Grace和Edsger面临一个矩阵恢复挑战。由于病毒,矩阵元素部分丢失,但保留了行和列的异或和。文章介绍了如何通过构建图并寻找最大生成树来确定最少恢复时间,提供了一种O(n^2 log n)的解决方案。
摘要由CSDN通过智能技术生成

Kick Start 2021 Round A:

Checksum

Grace and Edsger are constructing a N×N boolean matrix A. The element in i-th row and j-th column is represented by Ai,j. They decide to note down the checksum (defined as bitwise XOR of given list of elements) along each row and column. Checksum of i-th row is represented as Ri. Checksum of j-th column is represented as Cj.
For example, if N=2, A=[1101], then R=[10] and C=[01].
Once they finished the matrix, Edsger stores the matrix in his computer. However, due to a virus, some of the elements in matrix A are replaced with −1 in Edsger’s computer. Luckily, Edsger still remembers the checksum values. He would like to restore the matrix, and reaches out to Grace for help. After some investigation, it will take Bi,j hours for Grace to recover the original value of Ai,j from the disk. Given the final matrix A, cost matrix B, and checksums along each row ® and column ©, can you help Grace decide on the minimum total number of hours needed in order to restore the original matrix A?

题目大意

Grace在尝试复原一个N × \times ×N的01矩阵(1 ≤ \leq N ≤ \leq 500),第i行,第j列的值为Ai,j(若Ai,j=-1的,表示值未知)。他已知每一行与每一列的异或和Ri,Ci,同时他也可以花费Bi,j小时(1 ≤ \leq Bi,j ≤ \leq 1000)去向Grace询问Ai,j的值。他最少需要多少时间才能复原矩阵?

思路分析

注意到,对于任何一行或一列,如果我们只有一个值是未知的,我们可以用所有其他值异或上异或和便可以求解这个值;如果有至少两个位置未知,那么我们便无法求解。考虑每一个Ai,j=-1的位置,我们每一行和每一列最多有1个值是可以通过当列(行)的异或值自己求出来的,那么我们应该尽量选取Bi,j更大的值来节省时间。怎样找到这样的点的集合呢?由于每列(行)最多使用一次,我们可以把每一行(列)看成一个点,可以把每个Ai,j看成是把第i行和第j列连接起来的边,在生成图中找最大生成树,组成最大生成树的边集就是我们要找的点集。答案为所有Ai,j=-1的Bi,j之和减去最大生成树的边权和。一共最多n2个点,那么这个算法时间复杂度是O(n2log(n2)),也就是O(n2log(n))的。

重要代码示例

for(int i=0;i<n;i++)
		{
			for(int j=0;j<n;j++)
			{
				if(a[i][j]==-1)
				{
            		ans+=b[i][j];
            		vec[b[i][j]].push_back({i,j+n});//连接第i行,第j列,边权为b[i][j]
				}
			}
        }
        //最大生成树
        for(int val=1000;val;val--)//权值从大到小
        {
            for(auto p:vec[val])
            {
                int x=ff(p.first),y=ff(p.second);
                if(x!=y)
				{
                    ans-=val;//找到了生成树里的边
                    fa[x]=y;
                }
            }
		}

本题难度比前三题要高出一些,转成图论问题的思路更多是靠经验了,不过整体难度并不高。那么本轮比赛题解至此完结!由于是开年第二轮,总体还是非常友好的,很适合新手提高信心参加!

本轮所有题目题解(已完结)

K-Goodness String
L-Shaped Plots
Rabbit House
Checksum

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值