hdu1801 01翻转 贪心
题目描述:
对于给出的一个n*m的矩形,它由1和0构成,现在给你一个r*c的矩形空间可以选择,且可以选择无数次(被选中的范围内01翻转),要求问将这个01矩阵全部变成0的最少需要翻多少次,且如果无法实现输出-1
题目分析:
对于单个位置而言,不是0就是1,且如果是1则必须接受反转,对某个点来说,反转1,3,5,7...次是一样的,翻转0,2,4,6,8...次是一样的,所以对于矩形N*M中的任何一个点只有反转和不反转两种选择,而如果是1,则必须接受反转,所以我们需要做的就是从左上开始,一行一行每个位置依次判断,(将这个点作为你反转矩阵r*c的左上角)这样能保证主动去反转的每个点只翻一次,且不会被后面的翻转情况所影响(翻前面的点时后面的下面的点可能会一同被反转,但是没有关系,我们接下来会去依次判断,我们的循环就是从上往下,从左往右)
这是一种贪心的思维,我们每次需要翻转的情况都是必须翻的,而一旦遇到需要反转,但是剩余的选择空间不足以容纳以该点为左上角的r*c的矩阵时,返回-1,翻转成功计数器+1
代码:
1 #include<iostream> 2 using namespace std; 3 4 char mat[105][105]; 5 int n, m, r, c; 6 7 int run(){ 8 int ans = 0; 9 for(int i = 1; i <= n; i++){ 10 for(int j = 1; j <= m; j++){ 11 if(mat[i][j] == '1'){ 12 int row = i+r-1; 13 int col = j+c-1; 14 if(row <= n && col <= m){ 15 ans++; 16 for(int k = i; k <= row; k++){ 17 for(int l = j; l <= col; l++){ 18 if(mat[k][l] == '1') mat[k][l] = '0'; 19 else mat[k][l] = '1'; 20 } 21 } 22 }else{ 23 return 0; 24 } 25 } 26 } 27 } 28 return ans; 29 } 30 31 int main(){ 32 while(scanf("%d%d%d%d", &n, &m, &r, &c) != EOF){ 33 if(n == 0) break; 34 for(int i = 1; i <= n; i++){ 35 for(int j = 1; j <= m; j++){ 36 cin>>mat[i][j]; 37 } 38 } 39 int cnt = run(); 40 if(cnt == 0) printf("-1\n"); 41 else printf("%d\n", cnt); 42 } 43 return 0; 44 }
如果有任何意见请在评论区积极留言
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET10 - 预览版1新功能体验(一)