• CF1391D 【505】


    题目翻译

    有一个 (n imes m)(01) 矩阵,可以修改一些位置,使得矩阵中的所有 长度为偶数的正方形子矩阵里的 (1) 的数量为奇数。求出最少的修改次数。

    如果无论怎么修改都无法完成,输出 (-1)

    思路

    显然一个 (4 imes 4) 的子矩阵可以由 (4)(2 imes 2) 的矩阵构成。

    但是如果这 (4)(2 imes 2) 的矩阵中 (1) 的数量都是奇数,那么 (4 imes 4) 大小的矩阵里 (1) 的数量就是:奇 (+)(+)(+)(=) 偶 ,这显然是自相矛盾的。

    所以,当出现了一个 (4 imes 4) 大小的子矩阵即 (n ge 4) 时,直接输出 (-1) 即可。

    而如果没有 (4 imes 4) 的矩阵,那么就意味着只要考虑 (2 imes 2) 的矩阵。

    因为题目告诉我们 (nle m) ,故我们只需要考虑 (n==1)(2)(3) 三种情况 。

    可以分开讨论三种情况:

    • (n == 1) 时:

      所有情况都满足要求,输出 (0)

    • (n == 2) 时:

      很容易想到,如果每一个子矩阵都满足要求,那么列与列之间的奇偶关系一定是:奇偶奇偶奇偶奇偶... 或者是:偶奇偶奇偶奇偶奇... 。

      而如果一列转换奇偶性,那么只要修改一次。

      所以可以直接算变为两种情况的代价,然后在这两种情况里取最小值即可。

    • (n == 3) 时:

      (n==2) 的情况一样,如果每一个子矩阵都满足要求,那么对于每一列的上面两行和下面两行,他们之间的奇偶关系也是互相交错的。

      那么如果一列的上面两行要修改奇偶性,同样可以只修改一次。

      但这一次可以修改在第一行,也可以修改在第二行。如果修改在第一行那么就只有上面两行的奇偶性改变;而如果修改在第二行那么上面两行和下面两行的奇偶性都会改变。

      而在下面两行的修改同理。

      所以只要这一列中,不论是上面两行还是下面两行要转变奇偶性,最多都只要修改一次。

    Code

    #include<bits/stdc++.h>
    
    using namespace std;
    
    int read()
    {
    	int ans=0,f=1;
    	char c=getchar();
    	while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
    	while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
    	return ans*f;
    }
    
    const int N=1e6+5;
    int n,m,mmap[5][N],ans;
    //因为 n<=m 放第一维只要开到3
    char s[N];
    
    inline int get_2_ans(int x);
    //计算 n=2 时的答案,x 为第一列的奇偶性
      
    inline int get_3_ans(int x,int y);
    //计算 n=3 时的答案,x 为第一列上面两行的奇偶性,y 为第一列下面两行的奇偶性
    
    int main()
    {
    	n=read();m=read();
    	if(n>=4)
    		printf("-1
    ");
    	else if(n==1)
    		printf("0
    ");
    	else if(n==2) //n==2 的情况
    	{
    		for(int i=1;i<=n;++i)
    		{
    			scanf("%s",s+1);
    			for(int j=1;j<=m;++j)
    				mmap[i][j]=s[j]-'0';
    		}
    		ans=min(get_2_ans(0),get_2_ans(1));
    		printf("%d
    ",ans);
    	}
    	else //n==3 的情况
    	{
    		for(int i=1;i<=n;++i)
    		{
    			scanf("%s",s+1);
    			for(int j=1;j<=m;++j)
    				mmap[i][j]=s[j]-'0';
    		}
    		ans=0x7fffffff;
     		//枚举每一种奇偶性,统计答案
    		ans=min(ans,get_3_ans(0,0));
    		ans=min(ans,get_3_ans(1,0));
    		ans=min(ans,get_3_ans(0,1));
    		ans=min(ans,get_3_ans(1,1));
    		printf("%d
    ",ans); 
    	}
    	return 0;
    } 
    
    inline int get_2_ans(int x)
    {
    	int res=0;
    	for(int i=1;i<=m;++i)
    	{
             // 如果这一列的奇偶性目标不同,修改一次
    		if((mmap[1][i]+mmap[2][i])%2!=x)
    			res++;
    		x=!x; // 转换奇偶性
    	}
    	return res;
    }
    
    inline int get_3_ans(int x,int y)
    {
    	int res=0;
    	for(int i=1;i<=m;++i)
    	{
      		// 如果这一列的上面两行或者下丽两行的奇偶性目标不同,修改一次
    		if((mmap[1][i]+mmap[2][i])%2!=x)
    			res++;
    		else if((mmap[2][i]+mmap[3][i])%2!=y)
    			res++;
    		x=!x;y=!y;  // 转换奇偶性
    	}
    	return res;
    }
    
  • 相关阅读:
    常见面试之机器学习算法思想简单梳理
    机器学习其实比你想的更简单
    机器学习自学指南
    机器学习算法之旅
    我们需要解决的机器学习问题
    机器学习常见算法分类汇总
    机器学习算法基础概念学习总结
    github cheat sheet
    ubuntu kylin 14.10 安装deepin_music
    安装k-vim遇到的错误
  • 原文地址:https://www.cnblogs.com/blackbird137/p/13550420.html
Copyright © 2020-2023  润新知