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

2024-02-06 15:44

本文主要是介绍牛客——牛可乐的翻转游戏(状压,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位的整数来表示集合的状态,其中每一位表示集合中对应元素的存在与否。

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

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

这篇关于牛客——牛可乐的翻转游戏(状压,dfs)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/684791

相关文章

windos server2022里的DFS配置的实现

《windosserver2022里的DFS配置的实现》DFS是WindowsServer操作系统提供的一种功能,用于在多台服务器上集中管理共享文件夹和文件的分布式存储解决方案,本文就来介绍一下wi... 目录什么是DFS?优势:应用场景:DFS配置步骤什么是DFS?DFS指的是分布式文件系统(Distr

Python开发围棋游戏的实例代码(实现全部功能)

《Python开发围棋游戏的实例代码(实现全部功能)》围棋是一种古老而复杂的策略棋类游戏,起源于中国,已有超过2500年的历史,本文介绍了如何用Python开发一个简单的围棋游戏,实例代码涵盖了游戏的... 目录1. 围棋游戏概述1.1 游戏规则1.2 游戏设计思路2. 环境准备3. 创建棋盘3.1 棋盘类

hdu 2489 (dfs枚举 + prim)

题意: 对于一棵顶点和边都有权值的树,使用下面的等式来计算Ratio 给定一个n 个顶点的完全图及它所有顶点和边的权值,找到一个该图含有m 个顶点的子图,并且让这个子图的Ratio 值在所有m 个顶点的树中最小。 解析: 因为数据量不大,先用dfs枚举搭配出m个子节点,算出点和,然后套个prim算出边和,每次比较大小即可。 dfs没有写好,A的老泪纵横。 错在把index在d

poj 3050 dfs + set的妙用

题意: 给一个5x5的矩阵,求由多少个由连续6个元素组成的不一样的字符的个数。 解析: dfs + set去重搞定。 代码: #include <iostream>#include <cstdio>#include <set>#include <cstdlib>#include <algorithm>#include <cstring>#include <cm

国产游戏崛起:技术革新与文化自信的双重推动

近年来,国产游戏行业发展迅猛,技术水平和作品质量均得到了显著提升。特别是以《黑神话:悟空》为代表的一系列优秀作品,成功打破了过去中国游戏市场以手游和网游为主的局限,向全球玩家展示了中国在单机游戏领域的实力与潜力。随着中国开发者在画面渲染、物理引擎、AI 技术和服务器架构等方面取得了显著进展,国产游戏正逐步赢得国际市场的认可。然而,面对全球游戏行业的激烈竞争,国产游戏技术依然面临诸多挑战,未来的

ural 1149. Sinus Dances dfs

1149. Sinus Dances Time limit: 1.0 second Memory limit: 64 MB Let  An = sin(1–sin(2+sin(3–sin(4+…sin( n))…) Let  Sn = (…( A 1+ n) A 2+ n–1) A 3+…+2) An+1 For given  N print  SN Input One

hdu 6198 dfs枚举找规律+矩阵乘法

number number number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description We define a sequence  F : ⋅   F0=0,F1=1 ; ⋅   Fn=Fn

每日一题|牛客竞赛|四舍五入|字符串+贪心+模拟

每日一题|四舍五入 四舍五入 心有猛虎,细嗅蔷薇。你好朋友,这里是锅巴的C\C++学习笔记,常言道,不积跬步无以至千里,希望有朝一日我们积累的滴水可以击穿顽石。 四舍五入 题目: 牛牛发明了一种新的四舍五入应用于整数,对个位四舍五入,规则如下 12345->12350 12399->12400 输入描述: 输入一个整数n(0<=n<=109 ) 输出描述: 输出一个整数

深度优先(DFS)和广度优先(BFS)——算法

深度优先 深度优先搜索算法(英语:Depth-First-Search,DFS)是一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支,当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访

火柴游戏java版

代码 /*** 火柴游戏* <p>* <li>有24根火柴</li>* <li>组成 A + B = C 等式</li>* <li>总共有多少种适合方式?</li>* <br>* <h>分析:</h>* <li>除去"+"、"="四根,最多可用火柴根数20根。</li>* <li>全部用两根组合成"1",最大数值为1111。使用枚举法,A和B范围在0~1111,C为A+B。判断</li>** @