Message CodeForces - 157C 滑動門技巧

傳送門

題目大意: 有一個字符串s, 從中任取一個子串, 然後改變儘量少的次數使它變成字符串u。

改變規則如下(修改取的子串, 不是字符串s):

  • 在字符串首或尾添加一個字符

  • 在字符串首或尾刪去一個字符

  • 在字符串任意一個位置修改一個字符

求修改的最少次數

解題思路: 找一個子串,與目標串對應位置最多有幾個相同的(也就是要改動最少的), 這樣我們總是匹配與u的長度一樣長的字符串即可, 但是有個問題就是, 如果u串中後半部分與s串的開頭匹配就被忽略了, 因此我們假想s前面還有一個長度爲u長度的空串, 讓u從這個空串的開頭開始匹配, 只要是空串那麼一定需要補一個字符。

代碼:

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

char s[2050], u[2050];

int main()
{
	scanf("%s%s", s, u);
	int ls = strlen(s);
	int lu = strlen(u);
	int ans = lu;
	int j, cur;
	for(int i=0; i<ls+lu; ++i)
	{
		for(cur=j=0; j<lu; ++j) //根據u的長度挨個匹配看看是否相同, 如果不相同就要改動一次
		{
			//i 爲從空串開頭開始, i-lu就是s的下標,i-lu+j < 0 表示當前還在空串, 因此需要補一個字符。
			//如果i-lu +j >= ls 表示長度超越了s的長度, 因此需要在後面補一個字符
			//在s的範圍之內,就看是否相等了, 如果不想等就要改變一個字符
			cur += (i-lu+j >= 0 && i+j < lu+ls) ? s[i-lu+j] != u[j] : 1;
		}
		ans = min(ans, cur);
	}
	cout << ans << endl;
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章