牛客——牛可乐的翻转游戏(状压,dfs)

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

题目描述

牛可乐发明了一种新型的翻转游戏!

在一个有 nnn 行 mmm 列的棋盘上,每个格子摆放有一枚棋子,每一枚棋子的颜色要么是黑色,要么是白色。每次操作牛可乐可以选择一枚棋子,将它的颜色翻转(黑变白,白变黑),同时将这枚棋子上下左右相邻的四枚棋子的颜色翻转(如果对应位置有棋子的话)。

牛可乐想请你帮他判断一下,能否通过多次操作将所有棋子都变成黑色或者白色?如果可以,最小操作次数又是多少呢?

输入描述:

第一行两个整数 n,m(1≤n≤100,1≤m≤10)n,m(1\leq n\leq 100,1\leq m\leq 10)n,m(1≤n≤100,1≤m≤10),代表棋盘的行数和列数。之后 nnn 行,每行 mmm 个数字,第 iii 个数字如果为 000 ,代表对应位置的棋子为白色,如果为 111 则为黑色。

输出描述:

如果无法将所有棋子变成一个颜色,输出 "Impossible"(不含引号),否则输出变成一个颜色的最小操作次数。

#include<bits/stdc++.h>
using namespace std;int n, m;
string c[120], d[120];void overturn(int x, int y) {int dx[6] = {0, 0, 0, 0, 1, -1};int dy[6] = {0, 0, 1, -1, 0, 0};for (int i = 1; i <= 5; i++) {int a = x + dx[i];int b = y + dy[i];if (a >= 0  && b >= 0 ) {d[a][b] = (d[a][b] == '0' ? '1' : '0');}}
}int recurrence(int state, char target) {int step = 0;for (int i = 0; i < n; i++) {d[i] = c[i];}for (int i = 0; i < m; i++) {if (state & (1 << i)) {step++;overturn(0, i);}}for (int i = 1; i < n; i++) {for (int j = 0; j < m; j++) {if (d[i-1][j] != target) {step++;overturn(i, j);}}}for (int i = 0; i < m; i++) {if (d[n-1][i] != target) {return 1000;}}return step;
}int main() {cin >> n >> m;for (int i = 0; i < n; i++) {cin >> c[i];}int ans = 1000;for (int i = 0; i < (1 << m); i++) {ans = min(ans, recurrence(i, '0'));ans = min(ans, recurrence(i, '1'));}if (ans == 1000) {cout << "Impossible";} else {cout << ans;}return 0;
}
#include<iostream>
using namespace std;
const int N=105,M=1200;
int a1[N],a2[N],cnt[M],n,m;void Init(){for(int i=0;i<M;++i){for(int j=0;j<m;++j){if(i&(1<<j)) ++cnt[i];}}
}int dfs(int pre,int op,int *a){int res=0;for(int i=1;i<n;++i){res+=cnt[pre];int cur=( (pre^(pre<<1)^(pre>>1)^op)&( (1<<m)-1) )^a[i];op=pre;	pre=cur;}if(pre==0) return res;else return 1e9;}int main(){char num;cin>>n>>m;Init();for(int i=0;i<n;++i){for(int j=1;j<=m;++j){cin>>num;if(num=='1') a1[i]|=1<<(m-j);else a2[i]|=1<<(m-j);}}//for(int i=0;i<n;++i) cout<<a1[i]<<" "<<a2[i]<<endl;int res=1e9;for(int i=0;i<(1<<m);++i){res=min(res,cnt[i]+dfs(( (i^(i<<1)^(i>>1))&( (1<<m)-1) )^a1[0] ,i,a1));res=min(res,cnt[i]+dfs(( (i^(i<<1)^(i>>1))&( (1<<m)-1) )^a2[0] ,i,a2));}if(res==1e9) cout<<"Impossible";else cout<<res;return 0;
}
#include <iostream>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
int change[120];
int map[120];
int m,n;
int wei(int num){int sum=0;while(num){sum++;num&=num-1;}return sum;
}
int wei(int a[]){int step=0x3f3f3f;for(change[0]=0;change[0]<(1<<m);change[0]++){map[0]=a[0];int sum=0;for(int j=0;j<n;j++){sum+=wei(change[j]);map[j]=map[j]^change[j]^((change[j]<<1)&((1<<m)-1))^(change[j]>>1);map[j+1]=a[j+1]^change[j];change[j+1]=map[j];}if(!map[n-1])step=min(sum,step);}return step;
}
int main() {int a[120];int b[120];memset(a,0,sizeof(a));memset(b,0,sizeof(b));cin>>n>>m;char d;getchar(); for(int i=0;i<n;i++){for(int j=0;j<m;j++){d=getchar();d=='0'?a[i]=a[i]|(1<<j):b[i]=b[i]|(1<<j);}getchar();}int ans=0x3f3f3f;ans=min(wei(a),wei(b));if(ans>m*n)cout<<"Impossible"<<endl;else cout<<ans<<endl;return 0;
}

这种题好难理解呀,搜了好多题解,感觉懂了,但是再遇到也不一定会写,所以这种题还是先放一放吧。

补充:

状压是一种常用于位运算的技巧,用于表示和处理集合等离散对象的状态。它通过使用整数的二进制位来表示对象或状态的某些特征,以达到节省空间和提高效率的目的。

在状压中,通常使用整数的二进制位来表示某个集合的状态,其中每一位可以表示集合中的某个元素是否存在或某个状态是否满足某种条件。例如,对于一个大小为n的集合,可以使用一个n位的整数来表示集合的状态,其中每一位表示集合中对应元素的存在与否。

状压常用于解决组合数学、动态规划、图论等问题,特别是当集合的大小较小且需要频繁判断和操作集合的状态时,状压可以显著提高算法的效率和减少空间复杂度。

使用状压技巧需要熟悉位运算的基本操作,例如与(&)、或(|)、异或(^)等,以及位移操作(<<、>>)等。同时,也需要注意处理位运算可能导致的溢出和边界情况。

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

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

相关文章

C语言:函数

创作不易&#xff0c;友友们给个三连吧&#xff01;&#xff01; 一、函数的概念 数学中我们见过函数的概念&#xff0c;例如ykxb&#xff0c;k和b都是常数&#xff0c;给任意一个x就可以得到y 而C语言也引入了函数&#xff08;function&#xff09;这个概念&#xff0c;C语…

Java学习16-- 面向对象学习45. 面向对象三大特征抽象类和接口

面向对象学习4. 面向对象三大特征 1封装&#xff1a;高内聚(内部细节自己用&#xff0c;外部不能介入)&#xff0c;低耦合(保留很少接口给外部使用)&#xff0c;信息隐藏&#xff08;禁止外界直接访问内部数据(private)&#xff0c;如需要&#xff0c;可通过get/set接口访问&a…

1Panel面板如何安装并结合内网穿透实现远程访问本地管理界面

文章目录 前言1. Linux 安装1Panel2. 安装cpolar内网穿透3. 配置1Panel公网访问地址4. 公网远程访问1Panel管理界面5. 固定1Panel公网地址 前言 1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。高效管理,通过 Web 端轻松管理 Linux 服务器&#xff0c;包括主机监控、…

springboot项目热部署实现(Spring Boot DevTools方式)

文章目录 Spring Boot DevTools简介Spring Boot DevTools原理spring Boot Devtools优缺点Spring Boot DevTools集成步骤第一步&#xff1a;添加maven依赖第二步&#xff1a;IDEA热部署配置 Spring Boot DevTools简介 Spring Boot DevTools是Spring Boot提供的一个开发工具&…

机器人运动学林沛群——变换矩阵

对于仅有移动&#xff0c;由上图可知&#xff1a; A P B P A P B o r g ^AP^BP^AP_{B org} APBPAPBorg​ 对于仅有转动&#xff0c;可得&#xff1a; A P B A R B P ^AP^A_BR^BP APBA​RBP 将转动与移动混合后&#xff0c;可得&#xff1a; 一个例子 在向量中&#xff…

【JS】基于React的Next.js环境配置与示例

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍基于React的Next.js环境配置与示例。 学其所用&#xff0c;用其所学。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下…

Cuda编程注意小事项

1、函数执行空间标识符 用__global__修饰的函数称为核函数&#xff0c;般由主机调用,在设备中执行。如果使用动态并行&#xff0c;则也可以在核函数中调用自己或其他核函数。用__device__修饰的函数称为设备函数&#xff0c;只能被核函数或其他设备函数调用&#xff0c;在设备…

深兰科技陈海波出席CTDC2024第五届首席技术官领袖峰会:“民主化AI”的到来势如破竹

1月26日&#xff0c;CTDC 2024 第五届首席技术官领袖峰会暨出海创新峰会在上海举行。深兰科技创始人、董事长陈海波受邀出席了本届会议&#xff0c;并作为首个演讲嘉宾做了题为“前AGI时代的生产力革命范式”的行业分享。 作为国内顶级前瞻性技术峰会&#xff0c;CTDC首席技术官…

基于SpringBoot的美妆管理系统

文章目录 项目介绍主要功能截图&#xff1a;部分代码展示设计总结项目获取方式 &#x1f345; 作者主页&#xff1a;超级无敌暴龙战士塔塔开 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、 简历模板、学习资料、面试题库【关注我&#xff0c;都给你】 &…

Bagging的随机森林;Boosting的AdaBoost和GBDT

集成学习应用实践 import numpy as np import os %matplotlib inline import matplotlib import matplotlib.pyplot as plt plt.rcParams[axes.labelsize] 14 plt.rcParams[xtick.labelsize] 12 plt.rcParams[ytick.labelsize] 12 import warnings warnings.filterwarnin…

《Redis核心技术与实战》学习笔记1——基本架构:一个键值数据库包含什么?

基本架构&#xff1a;一个键值数据库包含什么&#xff1f; 文章目录 基本架构&#xff1a;一个键值数据库包含什么&#xff1f;可以存哪些数据&#xff1f;可以对数据做什么操作&#xff1f;采用什么访问模式&#xff1f;如何定位键值对的位置&#xff1f;不同操作的具体逻辑是…

Page 251~254 Win32 GUI项目,第二次分析

11行&#xff0c;本程序要创建的窗口的窗口过程(回调函数)&#xff0c;就是窗口用于处理消息的过程&#xff0c;返回值的类型是一个宏定义&#xff0c;即LRESULT&#xff0c;当操作系统分派消息给本窗口时&#xff0c;回调此函数&#xff0c;处理消息。 14行&#xff0c;使用全…