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

news2024/11/17 17:34:40

链接:登录—专业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.coloradmin.cn/o/1435547.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Simulink|光伏阵列模拟多类故障(开路/短路/阴影遮挡/老化)

目录 主要内容 模型研究 1.正常模型 2.断路故障 3.短路故障 4.阴影遮挡 5.老化模型 结果一览 1.U-I曲线 2.P-V曲线 下载链接 主要内容 该模型为光伏阵列模拟故障情况simulink模型&#xff0c;程序实现了多种故障方式下的光伏阵列输出功率-电压-电流关系特…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Radio组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之Radio组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、Radio组件 单选框&#xff0c;提供相应的用户交互选择项。 子组件 无。 接口 …

【前端素材】bootstrap4实现移动端电商APP页面 MobileShop(附源码)

一、需求分析 移动端电商网页是指为移动设备&#xff08;如智能手机和平板电脑&#xff09;优化设计的电子商务网页。它是在线商店的移动版本&#xff0c;旨在提供方便的购物体验和无缝的移动端操作。 移动端电商网页通常具有以下功能&#xff1a; 商品展示&#xff1a;移动端…

25.云原生ArgoCD高级之app of apps模式

文章目录 app of apps 模式介绍app如何管理apphelm方式管理kustomize方式管理 app of apps 模式介绍 通过一个app来管理其他app&#xff0c;当有多个项目要发布创建多个app比较麻烦&#xff0c;此时可以创建一个管理app&#xff0c;管理app创建后会创建其他app。比较适合项目环…

docker部署docker管理工具easydockerweb

重要提示 功能比较少,建议体验一下即可 安装 docker run -it -d -p 10041:3000 -e EDW_USERNAMEadmin -e EDW_PASSWORDadmin -v /var/run/docker.sock:/var/run/docker.sock qfdk/easydockerweb 使用 概览 镜像管理 容器管理

VS编译器对scanf函数不安全报错的解决办法(详细步骤)

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️ &#x1f64f;小杨水平有…

使用pandas将excel转成json格式

1.Excel数据 2.我们想要的JSON格式 {"0": {"raw_data1": "Sam","raw_data2": "Wong","raw_data3": "Good","layer": "12v1"},"1": {"raw_data1": "Lucy…

Redis(三)(实战篇)

查漏补缺 1.spring 事务失效 有时候我们需要在某个 Service 类的某个方法中&#xff0c;调用另外一个事务方法&#xff0c;比如&#xff1a; Service public class UserService {Autowiredprivate UserMapper userMapper;public void add(UserModel userModel) {userMapper.…

AR人脸106240点位检测解决方案

美摄科技针对企业需求推出了AR人脸106/240点位检测解决方案&#xff0c;为企业提供高效、精准的人脸识别服务&#xff0c;采用先进的人脸识别算法和机器学习技术&#xff0c;通过高精度、高速度的检测设备&#xff0c;对人脸进行快速、准确地定位和识别。该方案适用于各种应用场…

Vue-53、Vue技术vuex使用

vuex 是什么 1、概念 专门在Vue 中实现集中式状态&#xff08;数据&#xff09;管理的一个Vue 插件&#xff0c;对vue 应用中多个组件的共享状态进行集中式的 管理&#xff08;读/写&#xff09;&#xff0c;也是一种组件间通信的方式&#xff0c;且适用于任意组件间通信。2、…

大数据Zookeeper--案例

文章目录 服务器动态上下线监听案例需求需求分析具体实现测试 Zookeeper分布式锁案例原生Zookeeper实现分布式锁Curator框架实现分布式锁 Zookeeper面试重点选举机制生产集群安装多少zk合适zk常用命令 服务器动态上下线监听案例 需求 某分布式系统中&#xff0c;主节点可以有…

发现本地Elasticsearch版本 不兼容第三方管理工具 带大家在官网中寻找并下载指定版本的Elasticsearch

我们在 springboot 整合Elasticsearch时可能会出现版本不兼容异常 首先 大家要搞清楚 目前 Elasticsearch(ES)与springboot 市场版本互相的兼容情况 可以参考我的文章 springboot与Elasticsearch版本兼容对比 这里 我们想下载 其他版本 还是访问官网 https://www.elastic.co/…

探索LLM的意图识别能力

不可否认的是&#xff0c;LLM&#xff08;例如 OpenAI 的 GPT 系列&#xff09;将在不断发展的对话式 AI 领域发挥重要作用。 关于使用 ChatGPT 执行各种任务的帖子和文章不计其数。 GPT 有几个关键功能值得进一步探索&#xff0c;例如其摘要、分类和生成文本的能力。 其中&…

U盘误删的文件怎么找回?5个宝藏方法分享!

“我想问问大家&#xff0c;在使用u盘时如果不小心把很重要的文件删除了应该怎么办呀&#xff1f;有什么简单又快速的U盘文件恢复方法可以推荐吗&#xff1f;” U盘作为一种便携式的存储设备&#xff0c;在日常工作中扮演着重要的角色。然而&#xff0c;如果不小心误删了U盘中的…

SpringBoot:自动配置报告

自动配置报告demo&#xff1a;点击查看 LearnSpringBoot03AutoConfig 点击查看更多的SpringBoot教程 一、application.properties代码 #开启springboot debug模式 #自动配置报告 #Positive matches: 自动配置类启用了&#xff08;自动配置类匹配上了&#xff09;&#xff0c…

hexo和github.io博客的搭建

简要&#xff1a; 最近在牛客网上看到有很多应届毕业生大佬的求职简历上都写上了自己的博客地址&#xff0c;并且在acwing上看到图图佬&#xff0c;铅笔佬也有自己的博客地址&#xff0c;大部分都采用了自己搭建博客的方式&#xff0c;而不是用脏乱差的csdn来写博客。所以我也采…

电脑服务器离线安装.net framework 3.5解决方案(错误:0x8024402c )(如何确定当前系统是否安装NET Framework 3.5)

问题环境&#xff1a; 日常服务的搭建或多或少都会有需要到NET Framework 3.5的微软程序运行框架&#xff0c;本次介绍几种不同的安装方式主要解决运行在Windows 2012 以上的操作系统的服务。 NET Framework 3.5 是什么&#xff1f; .NET Framework是微软公司推出的程序运行框架…

利用LLM大模型生成sql的深入应用探究

Chat2DB 是一款有开源免费的多数据库客户端工具,和传统的数据库客户端软件Navicat、DBeaver 相比 Chat2DB 集成了 AIGC 的能力&#xff0c;能够将自然语言转换为 SQL&#xff0c;也可以将 SQL 转换为自然语言&#xff0c;可以给出研发人员 SQL 的优化建议&#xff0c;极大地提升…

YOLO-World——超级轻量级开放词汇目标检测方法

前言 目标检测一直是计算机视觉领域中不可忽视的基础挑战&#xff0c;对图像理解、机器人技术和自主驾驶等领域具有广泛应用。随着深度神经网络的发展&#xff0c;目标检测方面的研究取得了显著进展。尽管这些方法取得了成功&#xff0c;但它们存在一些限制&#xff0c;主要体…

Python __pycache__文件

pycharm配置位置 几个基本概念 源代码&#xff08;source code&#xff09; 我们每天编写的Python、Java、C等代码通常指的就是源代码&#xff0c;源代码的特点是人类可读。但是CPU只能读懂二进制&#xff0c;看不懂我们写的源代码&#xff0c;因此还需要进行编译&#xff08…