题目标题:翻硬币
小明正在玩一个“翻硬币”的游戏。
桌上放着排成一排的若干硬币。我们用 * 表示正面,用 o 表示反面(是小写字母,不是零)。
比如,可能情形是:**oo***oooo
如果同时翻转左边的两个硬币,则变为:oooo***oooo
现在小明的问题是:如果已知了初始状态和要达到的目标状态,每次只能同时翻转相邻的两个硬币,那么对特定的局le面,
最少要翻动多少次呢?
我们约定:把翻动相邻的两个硬币叫做一步操作,那么要求:
程序输入:
两行等长的字符串,分别表示初始状态和要达到的目标状态。每行的长度<1000
程序输出:
一个整数,表示最小操作步数
例如:
用户输入:
**********
o****o****
程序应该输出:
5
再例如:
用户输入:
*o**o***o***
*o***o**o***
程序应该输出:
1
资源约定:
峰值内存消耗 < 64M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include , 不能通过工程设置而省略常用头文件。
提交时,注意选择所期望的编译器类型。
解法一:
找规律,把每两个相邻的且不对应的字符看成一对,发现翻动的最小次数为两者序号之差,对应到例子一中就是位置0和位置5的字符不同,做差即可得5。例子二中就是位置4和位置5得字符不同,做差即可得1。依次类推,再举几个特殊例子验证,发现完全符合。并且如果是多对字符不同位置,那么结果就是分别做差再相加。c/c++代码如下
//翻硬币
#include<iostream>
#include<string.h>
using namespace std;
int main()
{
int n;
string src;
string target;
getline(cin, src);
getline(cin, target);
n = src.length();
int start = -1;
int ans = 0;
for(int i = 0;i < n;i++)
{
if(src[i] != target[i])
{
if(start == -1)//此时还未标记开始位置
{
start = i;
}
else//开始位置已经标记
{
ans += i - start;
}
}
}
cout << ans;
return 0;
}
解法二
采用BFS(广度优先搜索),穷举所有可能,一一比对,代码如下。
//翻硬币-DFS
#include<iostream>
#include<string.h>
#include<queue>
#include<set>
using namespace std;
typedef struct stateAndLevel
{
string str;
int level;
}stateAndLevel;
queue<stateAndLevel> q;
set<string> set1;
int main()
{
string src;
string target;
getline(cin, src);
getline(cin, target);
int n = src.length();
stateAndLevel first = {src, 0};
q.push(first);
while(!q.empty())
{
stateAndLevel front = q.front();
q.pop();
string basicString = front.str;
// 把已经处理过的字符串加入set中备查,避免往回翻的状态重复加入
set1.insert(basicString);
if(basicString.compare(target) == 0)
{
cout << front.level;
return 0;
}
// 模拟,依次翻转后加入队列中
for(int i = 0; i < n-1;i++)
{
string buffer;
buffer.insert(0, basicString);
if(buffer[i] == '*')
buffer[i] = 'o';
else
buffer[i] = '*';
if(buffer[i+1] == 'o')
buffer[i+1] = '*';
else
buffer[i+1] = 'o';
if(set1.find(buffer) == set1.end())
{
stateAndLevel sal = {buffer,front.level+1};
q.push(sal);
}
}
}
return 0;
}