问题描述

小明正在玩一个“翻硬币”的游戏。

桌上放着排成一排的若干硬币。我们用 * 表示正面,用 o 表示反面(是小写字母,不是零)。

比如,可能情形是:**oo***oooo

如果同时翻转左边的两个硬币,则变为:oooo***oooo

现在小明的问题是:如果已知了初始状态和要达到的目标状态,每次只能同时翻转相邻的两个硬币,那么对特定的局面,最少要翻动多少次呢?

我们约定:把翻动相邻的两个硬币叫做一步操作,那么要求:

输入格式

两行等长的字符串,分别表示初始状态和要达到的目标状态。每行的长度<1000

输出格式

一个整数,表示最小操作步数。

样例输入1

**********
o****o****

样例输出1

5

样例输入2

*o**o***o***
*o***o**o***

样例输出2

1

OJ版

#include<iostream>
#include <cstring>
using namespace std;

string s;//必须全部用全局变量 

void turnover(int i)
{
	s[i]=='*'?s[i]='o':s[i]='*';
	s[i+1]=='o'?s[i+1]='*':s[i+1]='o';
}

void task(string t)
{
	int k=0;
	for(int i=0;;i++)
	{	
		if(s[i+1]=='\0')break; 
		if(s[i]!=t[i])
		{
			turnover(i);k++;
		}
	}
	cout<<k<<endl; 
}

int main()
{
	string t;
	cin>>s;
	cin>>t;
	task(t);
 } 

动态解释版

#include<iostream>
#include <cstring>
using namespace std;

string s;//必须全部用全局变量 

void print(string s)
{
	cout<<"字符串现为:"<<s<<endl;
	//cout<<t<<endl;
}

void turnover(int i)
{
	cout<<"正在交换中:"<<endl;
	//cout<<"s"<<i<<"原为"<<s[i]<<endl;
	s[i]=='*'?s[i]='*':s[i]='o';
	//cout<<"s"<<i<<"现为"<<s[i]<<endl;
	print(s); 
	s[i+1]=='*'?s[i+1]='o':s[i+1]='*';
	print(s);
}

void task(string t)
{
	int k=0;
	for(int i=0;;i++)
	{	
		if(s[i+1]=='\0')break; 
		if(s[i]!=t[i])
		{
			cout<<i<<"位不相等"<<endl;
			cout<<i<<"轮发生了第"<<k<<"次交换"<<endl;
			turnover(i);k++;
			//print(s); 
		}
		else
		{
			cout<<i<<"位相等"<<endl;
			cout<<i<<"轮不交换"<<endl;
		}
	}
	cout<<"总步数:"<<k<<endl; 
}

int main()
{
	string t;
	cin>>s;
	cin>>t;
	cout<<"初始:"<<endl; 
	print(s);
	task(t);
	cout<<"交换结束:"<<endl; 
	print(s);
 } 

总结:

想要在函数中华修改字符串中的某一字符数组元素,必须将字符串设置为全局类型,在函数中直接修改,而不能作为函数参数进行修改,那样的修改是无效的。

为字符串赋值用双引号,为字符数组的某一元素赋值,用单引号。

熟记的if简写。

for循环的第二个条件可以直接省略不写,但那个分号不能省略。

不过、为什么从头翻到尾次数最少?还是不太明白。

贪心算法:

在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解。

posted on 2020-09-27 00:29  海月CSDN  阅读(164)  评论(0编辑  收藏  举报