蓝桥杯历届试题-翻硬币:看似bfs,实则找规律贪心
Posted C_YCBX Py_YYDS
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蓝桥杯历届试题-翻硬币:看似bfs,实则找规律贪心相关的知识,希望对你有一定的参考价值。
题目
题目解析
很快能有bfs思路,但是提交后会发现,无论怎么优化bfs都只能过一个,所以转化思路找规律。
我们手手动进行模拟后,发现其实每次改变连续的两个位置是有规律的,首先想要能进行转变,则两个字符串之间只能存在偶数个不同,且转变方式都是从一个不同的区域开始一直往上转变到使得两个不同的位置相同,这样描述不是很好理解,我们通过用1标记该下标位置两个字符串的字符是不同的,用0标记是相同的。则翻硬币的次数就是两个1的下标差值,换句话说就是不同字符的下标差值。
如图:
再复杂的情况也是一样的,只有1的个数相同二者才能进行转变。
题解
题解一:优化的双向bfs(可惜还是过不了,当作bfs复习了)
#include <iostream>
#include <string>
#include <tr1/unordered_set>
using namespace std;
using namespace std::tr1;
int main(){
string s1;
string s2;
cin>>s1;
cin>>s2;
unordered_set<string>Q1;
unordered_set<string>Q2;
unordered_set<string>visit;
Q1.insert(s1);
Q2.insert(s2);
int step = 0;
while(!Q1.empty()&&!Q2.empty()){
unordered_set<string>temp;
for(unordered_set<string>::iterator it = Q1.begin();it!=Q1.end();it++){
//双向bfs而言,visit慢半拍是最好的选择,否则只能在扩散的时候进行答案的判断了
visit.insert(*it);
if(Q2.count(*it)){
cout<<step;
return 0;
}
for(int j=0;j<(*it).size()-1;j++){
string tt = *it;
tt[j] = tt[j]=='*'?'o':'*';
tt[j+1] = tt[j+1]=='*'?'o':'*';
if(!visit.count(tt)){
temp.insert(tt);
}
}
}
step++;
Q1 = temp;
swap(Q1,Q2);
}
return -1;
}
题解二:真正的此题题解(能0ms过所有
#include <iostream>
#include <string>
using namespace std;
//把不相等的情况看作两两配对
int main(){
string s1;
string s2;
cin>>s1>>s2;
int sz = s1.size();
int sum = 0;
int pre_index = -1;
for (int i = 0; i < sz; ++i) {
if(s1[i]!=s2[i]){
if(pre_index!=-1){
sum+=(i-pre_index);
//这个pre_index已经被使用重置
pre_index = -1;
} else pre_index = i;
}
}
cout<<sum;
}
以上是关于蓝桥杯历届试题-翻硬币:看似bfs,实则找规律贪心的主要内容,如果未能解决你的问题,请参考以下文章