思路:此题主要在于对 '?' 的处理,在S[i-1]转换为S[i],对于S[i][j]='?'的情况,S[i][j]是否要改变。例如
+--
--?
+-+
若遇到'?',S[1][2]改变成 '+',则最小次数为6,而S[1][2]与S[0][2]相同则最小次数为5,
观察可知,当S[1][2]转变成'+'时,"+--"到"--+"需要2次,而"--+"到"+-+"时还是要将 '-'变成'+'需要一次,
而当 S[1][2]=S[0][2]时, "+--"到"---"只需一次,而 "---"到"+-+"也是一次,
因此转换中若只有'?'对于的 '-'或'+'转换,则保持不变,若还有其他的'-''+'转换,则说明 '?'可变可不变,因此可保留'?',在后面处理时则可以不去处理'?',即在S[i-1]转换成S[i]时,S[i-1]中的'?'代表 '-' '+'都可以表示
Code :
#include<iostream>
using namespace std;
const int MAX_N=55;
int n,m,T;
string str[MAX_N];
int main()
{
ios::sync_with_stdio(false);
cin>>T;
while(T--){
cin>>n>>m;
for(int i=1;i<=n;++i)
cin>>str[i];
str[0]="";
for(int i=0;i<m;++i)
str[0]+='-';
int ans=n;
for(int i=1;i<=n;++i)
{
int s1=0,s2=0;
for(int j=0;j<m;++j) //处理 !='?' 的情况
if(str[i][j]!='?'&&str[i-1][j]!='?'&&str[i-1][j]!=str[i][j]){
if(str[i][j]=='+') s1=1;
else s2=1;
}
for(int j=0;j<m;++j)
if(str[i][j]=='?') //判断其是否'-''+'都可以转换,若可以则用'?'表示(即不变)
if((str[i-1][j]=='+'&&!s2)||(str[i-1][j]=='-'&&!s1))
str[i][j]=str[i-1][j];
ans+=s1+s2;
}
cout<<ans<<endl;
}
return 0;
}