问题描述:
题目标题:翻硬币
小明正在玩一个“翻硬币”的游戏。
桌上放着排成一排的若干硬币。
我们用 * 表示正面,用 o 表示反面(是小写字母,不是零)。
比如,可能情形是:**oo***oooo
如果同时翻转左边的两个硬币,则变为:oooo***oooo
现在小明的问题是:如果已知了初始状态和要达到的目标状态,
每次只能同时翻转相邻的两个硬币,那么对特定的局面,最少要翻动多少次呢?
我们约定:把翻动相邻的两个硬币叫做一步操作,那么要求:
程序输入:
两行等长的字符串,分别表示初始状态和要达到的目标状态。
每行的长度<1000
程序输出:
一个整数,表示最小操作步数
例如:
用户输入:
**********
o****o****
程序应该输出:
5
再例如:
用户输入:
*o**o***o***
*o***o**o***
程序应该输出:
1
资源约定:
峰值内存消耗 < 64M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:
“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。
提交时,注意选择所期望的编译器类型。
解决方案:
#include<iostream>
#include<cstring>
using namespace std;
int main(){
char s1[1000]={0},s2[1000]={0};
int i=0;
gets(s1); //s1代表初始状态
gets(s2); //s2代表目标状态
int n1=strlen(s1),sum=0; //sum记录翻动硬币的次数
// printf("%d",n1);
while(1){ //多次重头到尾一直遍历
i=0;
while(i<=n1){
if(s1[i]!=s2[i]){ //若s1[i]与s2[i]不同,则改变s1[i]和s2[i+1]
sum++;
if(s1[i]=='*'){
s1[i]='o';
}
else{
s1[i]='*';
}
if(s1[i+1]=='*' && i+1<n1){
s1[i+1]='o';
}
else if(i+1<n1){
s1[i++]='*';
}
}
i++; //比较下一位
}
if(!strcmp(s1,s2)){ //如若两个字符串相同则结束循环
break;
}
}
// printf("%s\n",s1);
// printf("%s\n",s2);
printf("%d\n",sum);
return 0;
}
官方解法:
#include <iostream>
#include <queue>
#include <set>
using namespace std;
typedef struct stateAndLevel {
string str;
int level;
} stateAndLevel;
queue<stateAndLevel> queue1;
set<string> set1;
int n;
int main(int argc, const char *argv[]) {
string src;
string target;
getline(cin, src);
getline(cin, target);
n = src.length();
stateAndLevel first = {src, 0};
queue1.push(first);
while (!queue1.empty()) {
stateAndLevel &front = queue1.front();
queue1.pop();
string basicString = front.str;
if (basicString.compare(target) == 0) {
cout << front.level << endl;
return 0;
}
set1.insert(basicString);
for (int i = 0; i < n - 1; ++i) {
string buff;
buff.insert(0, basicString);
if (buff[i] == '*')
buff[i] = 'o';
else
buff[i] = '*';
if (buff[i + 1] == 'o')
buff[i + 1] = '*';
else
buff[i + 1] = 'o';
if (set1.find(buff) == set1.end()) {
stateAndLevel obj = {buff, front.level + 1};
queue1.push(obj);
}
}
// cout << queue1.size() << endl;
}
// cout << src << "\n" << target << endl;
return 0;
}