1.题面
2.题意
给出两个字符串p, 和 t, 只允许将p中的某个字符移动到字符串的末尾或是起始位置,问你至少经过几次移动可以将p变成t。3.思路
不过不要求最小的移动次数,我们可以选择任意一个字符作为起点,随后按次序将所有在他右边的字符一个个挪到末尾,所有在左边的字符一个个挪到起始,最后整个字符串p就会自然而然地变成t.
这样的次数最多是length(p)-1次,为了减少次数,我们就需要尽可能地利用原有的次序关系。
方法是找到一个最大长度l使得t中有一个长度为l的子串tt, p中有个长度为l的子序列两者相等。
(子串和子序列的定义请自行了解)
4.代码
/***************************************************************** > File Name: cpp_acm.cpp > Author: Uncle_Sugar > Mail: [email protected] > Created Time: Tue 21 Feb 2017 01:47:04 CST *****************************************************************/ # include <cstdio> # include <cstring> # include <cctype> # include <cmath> # include <cstdlib> # include <climits> # include <iostream> # include <iomanip> # include <set> # include <map> # include <vector> # include <stack> # include <queue> # include <algorithm> using namespace std; # define rep(i,a,b) for (i=a;i<=b;i++) # define rrep(i,a,b) for (i=b;i>=a;i--) # define mset(aim, val) memset(aim, val, sizeof(aim)) struct QuickIO{ QuickIO(){const int SZ = 1<<20; setvbuf(stdin ,new char[SZ],_IOFBF,SZ); setvbuf(stdout,new char[SZ],_IOFBF,SZ); } //*From programcaicai*// }QIO; template<class T>void PrintArray(T* first,T* last,char delim=' '){ for (;first!=last;first++) cout << *first << (first+1==last?'\n':delim); } /* 1.see the size of the input data before you select your algorithm 2.cin&cout is not recommended in ACM/ICPC 3.pay attention to the size you defined, for instance the size of edge is double the size of vertex */ const int debug = 1; const int size = 10 + 1000; const int INF = INT_MAX>>1; typedef long long ll; char p[size], t[size]; int main() { // std::ios::sync_with_stdio(false);cin.tie(0); scanf("%s%s", p, t); int len = strlen(p); int ans = -1; for (int i = 0; i < len; i++){ int tp = i, cnt = 0; for (int j = 0; j < len; j++){ if (p[j] == t[tp]){ tp++;cnt++; } } ans = max(cnt, ans); } printf("%d\n", len-ans); return 0; }