题意:
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;
}