pongo(英雄会)题解之最少操作次数的简易版
2013-12-20 23:11
281 查看
最近在看EPICS,大概过了一遍,感觉没什么效果,两周下来毫无进展,感觉在看不懂的时候就想玩,这周晚上玩了好多次CS,发现技术远不如前啊....
上周断断续续将AB数程序调出来了,鉴于那道题是比赛初赛题,现在还不写题解。如果一切顺利的话,29号可以到帝都拎着瓶子去膜拜下群里面的大神去,愿下周进展顺利。
这道”最少操作次数的简易版“,做的很不顺利,个人认为是pongo的测试样例出了问题,因为里面在用到字符串长度的时候,本来a和b的长度是一样的,但是取a的长度做计算就能通过,取b的长度做计算却不能通过,下面是题目:
求把第一个字符串变成第二个字符串的最小操作次数,且每次操作只能对第一个字符串中的某个字符移动到此字符串中的开头。
例如给定两个字符串“abcd" "bcad" ,输出:2,因为需要操作2次才能把"abcd"变成“bcad" ,方法是:abcd->cabd->bcad。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
由于算法基础薄弱,题做出来了,却不知道自己用的是什么算法,等后面有时间了一定得好好补下。
我的做法是:如果能找到 不移动 " 不必要移动的字符" 并且 "必须要移动的字符“ 只移动一次的的方法,那么这种方法的操作次数必然是最少的。
其中不必要移动字符是指 通过移动其他的字符而能使自己达到目的字符串中的位置,而必须要移动的字符恰恰相反;
现在需要做的是找出这两种字符,然后看能否找到"必须要移动的字符“ 只移动一次的方法;
看下面的例子,由上面的字符串 A 转换为下面的字符串 B :
![](http://img.blog.csdn.net/20131220224045843?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGh1X2V0ZXJuYWxjYw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
根据结果B中的字符位置的限定,我们来找出A中哪些字符是不必要移动,而另外一些无论如何都是需要被移走的,显然x、y、z是没必要移动(比如y可以通过移走e、f、g达到B中的正确位置),而g,f,e,d,c,b,a这7个字符是必须要移走的(因为如果f不被移走的话,那么z不可能成为最后一个字符,所以f是必须要移走的)。同时发现不必要移动的字符是目的字符串B中某个末尾子串,并且这个子串中的字符在A中的先后顺序与B中的顺序一致。
然后需要考虑的是有没有上述理想的移动方法呢?答案是有的,如下:
按B中除去末尾不必要移动的字符的子串的逆序来移动A中必要移动的元素,正好可以将A转换为B。
可以认为移动分为两步,删除所有必须移动的元素,再按合理顺序插入这些字符,即可以认为是将这些必要移动的字符先放在另外的串C,然后将这些字符按合理的顺序插入到xyz前面。自己可以动手画下上面的例子,依次移动g,f,e,d,c,b,a到开头即能将A转换为B。
由于题目只要求求最少的操作次数,那么我们只需统计需要被移走的字符个数即可,代码如下:
显然复杂度是O(length)
上周断断续续将AB数程序调出来了,鉴于那道题是比赛初赛题,现在还不写题解。如果一切顺利的话,29号可以到帝都拎着瓶子去膜拜下群里面的大神去,愿下周进展顺利。
这道”最少操作次数的简易版“,做的很不顺利,个人认为是pongo的测试样例出了问题,因为里面在用到字符串长度的时候,本来a和b的长度是一样的,但是取a的长度做计算就能通过,取b的长度做计算却不能通过,下面是题目:
题目详情:
给定两个字符串,仅由小写字母组成,它们包含了相同字符。求把第一个字符串变成第二个字符串的最小操作次数,且每次操作只能对第一个字符串中的某个字符移动到此字符串中的开头。
例如给定两个字符串“abcd" "bcad" ,输出:2,因为需要操作2次才能把"abcd"变成“bcad" ,方法是:abcd->cabd->bcad。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
由于算法基础薄弱,题做出来了,却不知道自己用的是什么算法,等后面有时间了一定得好好补下。
我的做法是:如果能找到 不移动 " 不必要移动的字符" 并且 "必须要移动的字符“ 只移动一次的的方法,那么这种方法的操作次数必然是最少的。
其中不必要移动字符是指 通过移动其他的字符而能使自己达到目的字符串中的位置,而必须要移动的字符恰恰相反;
现在需要做的是找出这两种字符,然后看能否找到"必须要移动的字符“ 只移动一次的方法;
看下面的例子,由上面的字符串 A 转换为下面的字符串 B :
根据结果B中的字符位置的限定,我们来找出A中哪些字符是不必要移动,而另外一些无论如何都是需要被移走的,显然x、y、z是没必要移动(比如y可以通过移走e、f、g达到B中的正确位置),而g,f,e,d,c,b,a这7个字符是必须要移走的(因为如果f不被移走的话,那么z不可能成为最后一个字符,所以f是必须要移走的)。同时发现不必要移动的字符是目的字符串B中某个末尾子串,并且这个子串中的字符在A中的先后顺序与B中的顺序一致。
然后需要考虑的是有没有上述理想的移动方法呢?答案是有的,如下:
按B中除去末尾不必要移动的字符的子串的逆序来移动A中必要移动的元素,正好可以将A转换为B。
可以认为移动分为两步,删除所有必须移动的元素,再按合理顺序插入这些字符,即可以认为是将这些必要移动的字符先放在另外的串C,然后将这些字符按合理的顺序插入到xyz前面。自己可以动手画下上面的例子,依次移动g,f,e,d,c,b,a到开头即能将A转换为B。
由于题目只要求求最少的操作次数,那么我们只需统计需要被移走的字符个数即可,代码如下:
#include <stdio.h> #include <iostream> #include <string> using namespace std; class Test { public: static int getNumber (string a,string b){ //int i=(int)(b.size())-1;//这样pongo提交会出错,可能是测试用例中有问题吧 int i=(int)(a.size())-1; int j=i; int res=0; while(j>=0){//&&i>=0 if(a[j]!=b[i]) ++res; else --i; --j; } return res; } }; //start 提示:自动阅卷起始唯一标识,请勿删除或增加。 int main() { cout<<Test::getNumber("abxcdyezfg", "abcdefgxyz")<<endl; } //end //提示:自动阅卷结束唯一标识,请勿删除或增加。
显然复杂度是O(length)
相关文章推荐
- 最少操作次数的简易版
- 最少操作次数的简易版
- 最少操作次数的简易版
- 英雄会 高校俱乐部 最少操作次数
- 最少操作次数的简易版
- 最小操作次数的简易版【解】--英雄会
- 正整数n到1的最少操作次数_Glodon(6)_20160923
- 实现一个函数,对一个正整数n,算得到1需要的最少操作次数?
- 对一个正整数n,算得到1需要的最少操作次数。
- 实现一个函数,对一个正整数n,算得到1需要的最少操作次数?
- 实现一个函数,对一个正整数n,算得到1需要的最少操作次数:
- 最少操作次数(英雄会)
- 1、对一个正整数算到1需要的最少操作次数
- cug1559 最少操作次数
- 比如你给它任意一个正整数,它可以按照一定的运算规则, 计算出得到1的最少操作次数。
- 面试题:对一个正整数n,算得到1需要的最少操作次数
- 计算最少操作次数。。。
- Hdu 5812 Distance(三种操作. 1.插入x 2.删除x 3.在集合中找到一个数y,使得y->x,每次能除以一个素数或者乘上一个素数,问最少的操作次数)
- 最少操作次数
- 动态规划求解-将字符串A变换为字符串B 所用的最少字符操作次数