Codeforce s Round 920 (Div. 3) G题 旋转矩阵,斜缀和,平移

Problem - G - Codeforces

目录

题意:

思路:

总思路:

旋转矩阵:

前缀和预处理:

平移的处理,尤其是越界的处理:

核心代码:


题意:

给你个n*m的矩阵,里面要么是目标' # ',要么是空的' . '。

还有值k,代表这样的范围:

我们有四个方向可选。图中黑点即是我们落脚点,可以随意选,要使黑色区域的目标'#'最多,输出这个最大值

思路:

总思路:

‘#’是随机给的,我们只能暴力。暴力上做优化即可。

如果这四种都做,代码是类同但细节处理太多,而只用一种方向然后旋转矩阵这样是等价的。

我们选择第三种,使用前缀和(列缀和,斜缀合)方便:

由于面积可能很大,每个落脚点都数时间消耗太多。我们可以发现相邻的是平移过去的,只差一列和斜着一列:

所以我们对上次的‘#’数目,加上这列的'#'数目,再减去斜着的'#'数目,就是这次的'#'数目了。

预处理出前缀和,这样平移时加的减的都可以直接算出来。(越界的处理需要注意)

旋转矩阵:

(这个C语言OJ就写过。我好像有一次没写出来,然后就有了心理阴影,其实很好写)

我们再创个二维char数组next,把旋转的写进这个数组,然后覆盖原数组即可。

我们可以借助个例子去想,比如顺时针旋转:

1 2 3 4      5 1		
5 6 7 8	     6 27 38 4

我们可以发现第一行变成了倒数第一列,而原来的列数变成了新的行数。

所以next[ j ][ chars.size()-1-i ] = chars[ i ][ j ]        (chars就是原始图)

vector<vector<char>>next(chars[0].size(), vector<char>(chars.size()));
for (int i = 0; i < chars.size(); i++)
{for (int j = 0; j < chars[0].size(); j++){next[j][chars.size()-1 - i] = chars[i][j];}
}
chars = next;

(注意新的图的n和m是变的。)

前缀和预处理:

可能没写过斜缀和。然后下标可以从1开始,我是写的从0开始的。

	int t = 4;while (t--){n = chars.size(), m = chars[0].size();vector<vector<int>>narr(n, vector<int>(m)), rd(n, vector<int>(m));for (int i = 0; i < n; i++){for (int j = 0; j < m; j++){if (i > 0)narr[i][j] = narr[i - 1][j] + (chars[i][j] == '#');elsenarr[i][j] = chars[i][j] == '#';}}for (int i = 0; i < n; i++){for (int j = 0; j < m; j++){if(i>0&&j>0)rd[i][j] = rd[i - 1][j - 1] + (chars[i][j] == '#');elserd[i][j] = chars[i][j] == '#';}}

平移的处理,尤其是越界的处理:

for (int i = 0; i < n; i++)
{int tmp = narr[min(i + k, n - 1)][0] - (i - 1 >= 0 ? narr[i - 1][0] : 0);ans = max(ans, tmp);for (int j = 1; j < m; j++)//右平移{//x,y:前一个位置最下面那个点int x = i + k, y = j-1;if (x >= n){y -= x - (n - 1);x = n - 1; }tmp += narr[min(i+k,n-1)][j] - (i - 1 >= 0 ? narr[i - 1][j] : 0);if(y>=0)tmp	-= rd[x][y] - (j - 1 - k - 1 >= 0&&i-1>=0 ? rd[i - 1][j - 1 - k - 1] : 0);ans = max(ans, tmp);}
}

代码中x,y就是1点。

1的列缀合-2的列缀合就是新增的'#'

3的斜缀合-4的斜缀合就是失去的'#'

最难处理的就是3越界后的斜缀合:

我们可以发现,不管下面什么情况越界,最后一行都是n-1。我们取n-1对应着的斜缀合即可。

x,y仍代表1点(见上面),(x,y-1)就是原来的斜缀合的点,现在往左上角移动了,行的变换数是等于列的变换数的,而行变换(x-(n-1)),那么列也减去这个,即行为n-1,列为y-1 - (x-(n-1))。

其余的越界是好处理的,代码里有我的处理情况。

核心代码:

void solve()
{int n, m, k;cin >> n >> m >> k;vector<vector<char>>chars(n, vector<char>(m));for (int i = 0; i < n; i++)for (int j = 0; j < m; j++)cin >> chars[i][j];int ans = 0;int t = 4;while (t--){n = chars.size(), m = chars[0].size();vector<vector<int>>narr(n, vector<int>(m)), rd(n, vector<int>(m));for (int i = 0; i < n; i++){for (int j = 0; j < m; j++){if (i > 0)narr[i][j] = narr[i - 1][j] + (chars[i][j] == '#');elsenarr[i][j] = chars[i][j] == '#';}}for (int i = 0; i < n; i++){for (int j = 0; j < m; j++){if(i>0&&j>0)rd[i][j] = rd[i - 1][j - 1] + (chars[i][j] == '#');elserd[i][j] = chars[i][j] == '#';}}for (int i = 0; i < n; i++){int tmp = narr[min(i + k, n - 1)][0] - (i - 1 >= 0 ? narr[i - 1][0] : 0);ans = max(ans, tmp);for (int j = 1; j < m; j++)//右平移{//x,y:前一个位置最下面那个点int x = i + k, y = j-1;if (x >= n){y -= x - (n - 1);x = n - 1; }tmp += narr[min(i+k,n-1)][j] - (i - 1 >= 0 ? narr[i - 1][j] : 0);if(y>=0)tmp	-= rd[x][y] - (j - 1 - k - 1 >= 0&&i-1>=0 ? rd[i - 1][j - 1 - k - 1] : 0);ans = max(ans, tmp);}}vector<vector<char>>next(chars[0].size(), vector<char>(chars.size()));for (int i = 0; i < chars.size(); i++){for (int j = 0; j < chars[0].size(); j++){next[j][chars.size()-1 - i] = chars[i][j];}}chars = next;}cout << ans << endl;
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int t; cin >> t;while (t--){solve();}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/416892.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

验证回文串[简单]

优质博文&#xff1a;IT-BLO-CN 一、题目 如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后&#xff0c;短语正着读和反着读都一样。则可以认为该短语是一个回文串。 字母和数字都属于字母数字字符。 给你一个字符串s&#xff0c;如果它是回文串&#xff…

李沐《动手学深度学习》多层感知机 深度学习相关概念

系列文章 李沐《动手学深度学习》预备知识 张量操作及数据处理 李沐《动手学深度学习》预备知识 线性代数及微积分 李沐《动手学深度学习》线性神经网络 线性回归 李沐《动手学深度学习》线性神经网络 softmax回归 李沐《动手学深度学习》多层感知机 模型概念和代码实现 目录 …

Deepin_Ubuntu_查看树形目录结构(tree)

Linux系统&#xff08;Deepin、Ubuntu&#xff09;中&#xff0c;可以使用tree命令来查看树形目录结构&#xff0c;下面是一些示例&#xff1a; 查看当前目录的树形结构&#xff1a; tree查看指定目录的树形结构&#xff0c;例如/etc/X11/fonts目录&#xff1a; tree /etc/X…

递归、搜索与回溯算法(专题一:递归)

往期文章&#xff08;希望小伙伴们在看这篇文章之前&#xff0c;看一下往期文章&#xff09; &#xff08;1&#xff09;递归、搜索与回溯算法&#xff08;专题零&#xff1a;解释回溯算法中涉及到的名词&#xff09;【回溯算法入门必看】-CSDN博客 接下来我会用几道题&#…

【JSON2WEB】01 WEB管理信息系统架构设计

WEB管理信息系统分三层设计&#xff0c;分别为DataBase数据库、REST2SQL后端、JSON2WEB前端&#xff0c;三层都可以单独部署。 1 DataBase数据库 数据库根据需要选型即可&#xff0c;不需要自己设计开发&#xff0c;一般管理信息系统都选关系数据库&#xff0c;比如Oracle、…

Android studio 简单登录APP设计

一、登录界面: 二、xml布局设计: <LinearLayoutandroid:id="@+id/linearLayout"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:layout_editor_absoluteX="…

AI大模型预先学习笔记一:transformer和fine tune技术介绍

一、商业观点&#xff1a;企业借助大模型获得业务增长可能 二、底层原理&#xff1a;transformer 1&#xff09;备注 ①下面每个步骤都是自回归的过程&#xff08;aotu-regressive&#xff09;&#xff1a;已输出内容的每个字作为输入&#xff0c;一起生成下一个字 ②合起来就…

Android期末项目:美食点餐APP的设计与实现

目录 1 项目基本信息 1.1 项目名称 1.2 开发运行环境 1.3 使用的核心类及组件 2 项目需求分析 2.1 APP管理员 2.2 APP用户 3 项目开发过程 3.1 APP功能模块 3.2 数据库设计 3.3具体实现 3.3.1 用户注册与登录 3.3.2 fragment首页界面 3.3.3 fragment不同界面切换…

11种开源即插即用模块汇总 !!(附论文和代码)

即插即用的模块就像是一盒乐高&#xff0c;让我们能快速组合各种设计好的模块&#xff0c;搭建出我们需要的模型&#xff0c;这样做不仅让建模速度提升&#xff0c;还保证了模型的创新性和有效性。 文章目录 1、SCConv&#xff1a;空间和通道重构卷积&#xff08;2023&#xff…

锐浪报表 Grid++Report 明细表格标题重复打印

一、问题提出 锐浪报表 GridReport&#xff0c;打印表格时&#xff0c;对于明细表格的标题&#xff0c;打开换页时&#xff0c;需要重复打印明细表格的标题&#xff0c;或取消打印明细表格的标题。见下表&#xff1a; 首页&#xff1a; 后续页&#xff1a;&#xff08;无明细表…

pytorch GPU版本安装 python windows

annanconda环境 创建虚拟环境 pytorch19_gpu create -n pytorch19_gpu python3.9 激活环境 conda activate pytorch19_gpu 查找CUDA版本是12.0&#xff0c;查找方式&#xff0c;win r输入cmd进入命令行模式&#xff0c;输入nvidia-smi&#xff0c;如下&#xff0c; 查找如…

js中实现 base64 与文件格式互转

文件转 base64 通过 reader.readAsDataURL 方法实现 function file2base64(fileObj){let fileAddress fileObj; //获取文件, fileObj 为文件对象let file new FileReader();file.readAsDataURL(fileAddress); // 获取文件url&#xff0c;过程中触发下方 onload 方法file.on…