博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Codeforces Round #243 (Div. 2)——Sereja and Table
阅读量:4353 次
发布时间:2019-06-07

本文共 2391 字,大约阅读时间需要 7 分钟。

看这个问题之前,能够先看看这个论文,说白了就是分类讨论,可是这个思想非常重要

  • 题意:
    首先给出联通块的定义:对于相邻(上下和左右)的同样的数字视为一个联通块
    现给一个n*m的仅仅有0和1的矩形和数字k,求出最小反转个数使得总体包含若干个矩形联通块(即每一个联通块均是矩形)(1 ≤ n, m ≤ 100; 1 ≤ k ≤ 10)
    假设最小次数比k大,输出-1
  • 分析:
    题目的特点是k比較小。也就是说反转的次数比較少,所以能够从这里入手。直接枚举全部的位置肯定是不行了,那么能够这样考虑:(最好还是设n>=m)假设n比k大,那么肯定有一些行是不会有反转的数字的,那么我们能够枚举每一行来处理;假设k比n大,这个时候n小于10,所以这时候我们就能够暴力枚举每一行的全部状态。然后处理。

    以上两种方法处理的时候均根据下边的图形特点,仅仅知道一行的时候就能够求出最小的总反转数

终于仅仅能是
01010...
10101...
...
的形状(当中一个字符代表一个矩形)

const int MAXN = 110;int ipt[MAXN][MAXN];int main(){//    freopen("in.txt", "r", stdin);	int n, m, k;	while (~RIII(n, m, k))	{		REP(i, n) REP(j, m) RI(ipt[i][j]);		if (n < m)		{			REP(i, n) FF(j, i + 1, m) swap(ipt[i][j], ipt[j][i]);			swap(n, m);		}		if (n > k)		{			int ans = INF;			REP(i, n)			{				int tans = 0;				REP(j, n)				{					int cnt = 0;					if (i == j) continue;					REP(k, m)					{						if (ipt[i][k] != ipt[j][k]) cnt++;					}					tans += min(cnt, m - cnt);				}				ans = min(ans, tans);			}			printf("%d\n", ans <= k ? ans: -1);		}		else		{			int ans = INF;			REP(i, n)			{				int all = 1 << m;				for (int q = 0; q < all; q++)				{					int diff = 0;					for (int t = 0, l = 1; t < m; l <<= 1, t++) if (((q & l) != 0) != ipt[i][t]) diff++;					if (diff > k) continue;					int tans = 0;					REP(j, n)					{						if (i == j) continue;						int cnt = 0;						for (int t = 0, l = 1; t < m; t++, l <<= 1) if (((q & l) != 0) != ipt[j][t]) cnt++;						tans += min(cnt, m - cnt);					}					ans = min(ans, diff + tans);				}			}			printf("%d\n", ans <= k ? ans: -1);		}	}	return 0;}

參照大神的代码后的一些细节改动:

const int MAXN = 110;int ipt[MAXN][MAXN];int main(){//    freopen("in.txt", "r", stdin);	int n, m, k;	while (~RIII(n, m, k))	{		int ans = INF, all = 1 << m;		REP(i, n) REP(j, m) RI(ipt[i][j]);		if (n < m)		{			REP(i, n) FF(j, i + 1, m) swap(ipt[i][j], ipt[j][i]);			swap(n, m);		}		if (n > k)		{			REP(i, n)			{				int tans = 0;				REP(j, n)				{					int cnt = 0;					REP(k, m)						cnt += ipt[i][k] ^ ipt[j][k];					tans += min(cnt, m - cnt);				}				ans = min(ans, tans);			}		}		else		{			for (int mask = 0; mask < all; mask++)			{				int tans = 0;				REP(i, n)				{					int cnt = 0;					REP(j, m) cnt += ipt[i][j] ^ (mask >> j & 1);					tans += min(cnt, m - cnt);				}				ans = min(ans, tans);			}		}		printf("%d\n", ans <= k ? ans: -1);	}	return 0;}

posted on
2017-07-26 18:48 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/mthoutai/p/7241352.html

你可能感兴趣的文章
静态链接与动态链接的区别
查看>>
如何使用mysql
查看>>
小D课堂 - 零基础入门SpringBoot2.X到实战_第11节 Logback日志框架介绍和SpringBoot整合实战_45、SpringBoot2.x日志讲解和Logback配置实战...
查看>>
类中的静态函数和非静态函数的区别
查看>>
windows 下安装Apache
查看>>
Fedora14 mount出现错误时解决办法【亲测有效】
查看>>
使用Visual Studio 2013进行UI自动化测试
查看>>
13-集体照
查看>>
读了曾国藩家书,,心态逐渐平和起来。搞技术的如果缺乏信念的指引,生活会很乏味无聊!...
查看>>
160809308周子济第六次作业
查看>>
大型Web应用运行时 PHP负载均衡指南
查看>>
计算机的组成
查看>>
CSS2-3常见的demo列子总结一
查看>>
sublime text3最新版本注册码(build 3143)
查看>>
linux使用技巧
查看>>
必背公式及常数
查看>>
利用CSS、JavaScript及Ajax实现图片预加载的三大方法
查看>>
js时间戳转时间格式
查看>>
Nginx配置文件nginx.conf中文详解(总结)
查看>>
Linux的用户态和内核态
查看>>