题目链接:http://codeforces.com/contest/838/problem/A

知识点:  (void)

题目大意:

  给一个 \(n \times m\) 的 01 矩阵,对于矩阵在 \(n \times m\) 这个范围外的可以都视为 0。将矩阵分为多个 \(k \times k\) 的小块 \((k>1, k \in Z)\),但是要变换矩阵上的元素,使每个小块都为 0 或者都为 1。求最少变换多少个元素可以满足要求。

解题思路:

  用 vector<int> point[i] 记录第 \(i\) 行的 1 的位置。然后从 2 开始枚举 \(k\) 到 max(n,m),(剪枝:由某一个 \(k\) 得到的答案一定会优于或等于由 \(n \times k (n > 1, n \in Z)\) 得到的答案。因此,我们考虑完 \(k\) 之后,对于 \(2k, 3k...\) 这些就都不用考虑了,也就是说我们只需考虑 \(k\) 是素数的情况),对于每一个 \(k\),先遍历它对应的每一个小方块的左上角的点,然后遍历每个小方块的每一行,用 lower_bound() 找出这一行中位于对应小方块中的 1 的个数,加起来得到小方块中 1 的总数。然后每个小方块需要变换的元素数就是 min(\(k^2\) - num_of_one, num_of_one) (注:\(k^2\)-num_of_one = num_of_zero),加起来就是对应这个 \(k\) 对应的总变换数,最终答案就取那个最小值。

AC代码:

 #include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f, maxn = ;
int vis[maxn];
char st[maxn][maxn];
vector<int> point[maxn];
int main() {
int n, m;
int num = ;
scanf("%d%d", &n, &m);
for (int i = ; i<n; i++) scanf("%s", st[i]);
for (int i = ; i<n; i++)
for (int j = ; j<m; j++) {
if (st[i][j] == '') {
point[i].push_back(j);
num++; //1的总个数
}
}
int maxk = max(n, m), ans = num;
int temp, fail, tone;
for (int k = ; k <= maxk; k++) {
if (vis[k]) continue;
else {
for (int i = k; i <= maxk; i += k) vis[i] = ;
} temp = , fail = , tone = ;
for (int i = ; i<n; i += k) {
if (tone >= num || fail) break; //如果找出了所有的1,那么就没有必要再继续遍历下去了,其他的都是0
for (int j = ; j<m; j += k) { //定左上角
if (tone >= num || fail) break;
int one = ;
for (int z1 = ; z1<k&&i + z1<n; z1++) {
if (tone >= num || fail) break;
int l = lower_bound(point[i + z1].begin(), point[i + z1].end(), j) - point[i + z1].begin();
int r = lower_bound(point[i + z1].begin(), point[i + z1].end(), j + k) - point[i + z1].begin();
one += r - l;
tone += r - l;
}
temp += min(k*k - one, one);
if (temp >= ans) { //如果发现temp已经大于或等于我们目前已知的最佳答案,那么也没有必要继续下去了
fail = ;
break;
}
}
}
if (temp<ans) ans = temp;
}
printf("%d\n", ans); return ;
}

CF838A的更多相关文章

随机推荐

  1. AndroidStudio提高编译速度的建议

    1.使用最新的Android gradle插件 Google tools team一直致力于提高android studio的编译速度,使用最新的gradle插件可以搞编译速度 在Android Gr ...

  2. (数据科学学习手札82)基于geopandas的空间数据分析——geoplot篇(上)

    本文示例代码和数据已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 在前面的基于geopandas的空间数据分 ...

  3. vue2.x学习笔记(二十七)

    接着前面的内容:https://www.cnblogs.com/yanggb/p/12682364.html. 单元测试 vue cli拥有开箱即用的通过jest或mocha进行单元测试的内置选项.官 ...

  4. 【React踩坑记五】React项目中引入并使用react-ace代码编辑插件(自定义列表提示)

    最近有一个引入sql编辑器插件的需求,要求代码高亮显示,代码智能提示,以及支持自定义代码提示列表等功能.中途在自定义代码提示列表中由于没有相关demo,所以踩了一些坑,遂将其整理如下,以便日后查看. ...

  5. 整整 Java 线程池

    为什么用线程池 用官方文档来说,线程池解决了两个问题: 一是在执行大量的异步任务时,因为线程池减少了任务开始前的准备工作,如频繁创建线程,启动线程等工作,提升了性能表现:二是提供了一种绑定资源和管理资 ...

  6. 新手上路:Laravel-控制器基础

    1.控制器在哪 Controller目录默认存放于app\Htpp\Controllers下,当然,你可以自定义这个目录: Controllers文件夹有一个控制器基类Controller.php,你 ...

  7. 数学--数论--HDU 1098 Ignatius's puzzle (费马小定理+打表)

    Ignatius's puzzle Problem Description Ignatius is poor at math,he falls across a puzzle problem,so h ...

  8. 2019年 ICPC亚洲区预赛(上海赛区)总结

    首先,我要说,我输了,输给了自己的无知,输给了自己的心态与实力. 上海区域赛,打铁而归,最终还是没有比过自己SLG的朋友.要说什么呢?实力的差距,还是说给自己的失败找借口?不能进入金牌区,为什么铜牌区 ...

  9. python 安装模块之pip install +模块名的换源写法

    1.采用国内源,加速下载模块的速度2.常用pip源(上一篇博客介绍过):– 豆瓣:https://pypi.douban.com/simple– 阿里:https://mirrors.aliyun.c ...

  10. 从零开始通过webhooks实现前端自动化

    1. 前置条件 有一台自己的服务器.比如阿里云,腾讯云之类 有远程仓库能够push代码,pull代码.比如github,或者码云 远程仓库有webhooks功能 2. 自动化部署流程 3. 构建流程 ...