基础算法_模拟 + 细节

题意:

1337 翻转游戏

这个游戏与灯有关,有M只灯排成一行,编号为0,1,…M-1.所有灯在游戏初始时都是灭的。这个游戏有N关,你需要按顺序一关关通过,每一关由一个M长的字符串LevS描述,串中每一个字符对应一盏灯,其中LevS[i]对应序号为i的灯。每个字符有三种可能,分别代表三种要求:
1)LevS[i]=’+‘表示在这关中灯i的状态必须是开着的;
2)LevS[i]=’-‘表示在这关中灯i的状态必须是关着的;
3)LevS[i]=’?'表示在这关中灯i的状态可以是开也可以是关,即没有要求;
要通过一关你需要首先把M个灯的开关状态调节成当前的LevS中要求的状态,然后你需要按下check按钮,如果状态合法则通过该关并开始下一关。
游戏中,你有三种操作,每种操作耗时一个单位时间:
1)选择一些灯,将这些选中的灯全部变成开状态;(注意只开一盏与同时开多盏,都用时一个单位)
2)选择一些灯,将这些选中的灯全部变成关状态;
3)按下check按钮,系统检测状态,合法则进入下一关。
现在你提前知道了N关游戏中各自LevS的状态,求从第1关开始到第N关通关最少花费多少个单位时间。

例如:游戏有两关一共4盏灯,第一关LevS为"+±-",第二关为 “–++”。你需要5步完成这个游戏,因为灯初始状态为"----",5个步骤依次是"+±-",check,"----","–++",check。

输入
多组测试数据,第一行一个整数T,表示数据个数,其中1<=T<=10
之后有T组相同结构的数据:
每组数据第一行包含两个整数N,M,其中1<=N,M<=50,注意N是关卡的数量,M是灯的数量
之后有N行,每行一个M长的字符串,表示该关的LevS,字符串只由’+’,’-’,’?'构成。

输出
每组数据输出一行一个整数,即通关最少需要用的单位时间。

输入样例
3
2 4
+±-
–++
2 4
±++
±++
4 2
++
+?
?+
++

输出样例
5
3
5

思路:

‘+’和‘-’的变换都没有问题
看这里,嘤嘤嘤!!

for(int j = 1;j <= m;j++){
	if(x[j] == '-'&&s[j] == '+') ok1 = 1;
	if(x[j] == '+'&&s[j] == '-') ok2 = 1;
}

但是对于‘-’和‘+’分别遇到‘?’时怎么处理呢??
我们以‘+’为例吧!!
‘+’‘+’‘+’‘-’
‘-’‘-’‘-’‘?’
‘+’‘-’‘+’‘-’
如果‘?’变成‘ - ’ 只需要 5 次
如果‘?’变成‘+’需要6次
保持不变也只需要5次。。
如果当前x和s的转换只有‘+’转成‘-’而且s中的‘?’所对应的x如果是‘+’’?‘就可以换成‘+’。。确定就是ans = ans + 1

如果当前转换中两者都出现了肯定ans = ans + 2了,这个’?’换成什么都可以,那就传下去吧hhh

上代码吧!!

代码实现:

#include<bits/stdc++.h>
using namespace std;
char s[100];
char x[100];
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		int n,m;
		scanf("%d%d",&n,&m);
		for(int i = 1;i <= m;i++) x[i] = '-';
		int ans = 0;
		for(int i = 1;i <= n;i++){
			scanf(" %s",s + 1);
			int ok1 = 0;
			int ok2 = 0;
			for(int j = 1;j <= m;j++){
				if(x[j] == '-'&&s[j] == '+') ok1 = 1;
				if(x[j] == '+'&&s[j] == '-') ok2 = 1;
			}
			if(ok1&&!ok2) ans++;
			if(!ok1&&ok2) ans++;
			if(ok1&&ok2) ans = ans + 2;
			ans++;
			for(int j = 1;j <= m;j++){
				if(s[j] == '?'){
					if(x[j] == '+'&&!ok2) x[j] = '+';
					else if(x[j] == '-'&&!ok1) x[j] = '-';
					else x[j] = '?';
				}
				else x[j] = s[j];
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值