Abbreviation ---- hackerrank
原创
©著作权归作者所有:来自51CTO博客作者wx634d08b5232a4的原创作品,请联系作者获取转载授权,否则将追究法律责任
---恢复内容开始---
https://www.hackerrank.com/contests/world-codesprint-6/challenges/abbr
给定两个串str和sub。
对于每个str中的小写字母,可以变成大写,其他小写字母,能无条件删除,问其能否变成sub
一开始的时候贪心,用个数组标记两个串中字母各有多少个,一直模拟。然后卡死在一组数据上。我也发现不了是什么数据。
那么就dp吧
考虑dp[i][j]表示在str中的第i位转变成sub中的第j位,是否可能。
dp[i][j] = 1表示可能。
那么,如果dp[i - 1][j - 1] = 1; 就是前面的已经转换完成。
对于第i个字符。str[i]。如果是小写,那么dp[i][j - 1] = 1是必然的。因为我可以无条件删除小写字母,就是因为本来的i - 1位和j - 1位是可以搭配的了,现在说第i位和第j - 1位也可以搭配,因为删除第i位就可以了,
同时,如果把str[i]转成大写字母,和sub[j]相等的话,就说明,dp[i][j] = 1;说明本位可以搭配。
否则,如果str[i]是大写字母,就只能看看是不是和sub[j]一样了。一样就dp[i][j] = 1;
最后只要看看dp[lenstr][lensub]是否等于1即可。就是最后末尾是否能转换成功。
注意的是,对于小写字母,它是可以无条件删除的,所以可能是dp[i][j - 1] = dp[lenstr][lensub]
所以枚举j要到lensub + 1 这样才能把状态一直传递下去
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = 1000 + 20;
bool dp[maxn][maxn];
char str[maxn];
char sub[maxn];
//void work () {
// memset (dp, 0, sizeof dp);
// scanf ("%s%s", str + 1, sub + 1);
// int lenstr = strlen (str + 1);
// int lensub = strlen (sub + 1);
// dp[1][1] = 1;
// for (int i = 1; i <= lenstr; ++i) {
// for (int j = 1; j <= lensub + 1; ++j) {
// if (dp[i][j]) {
// if (str[i] >= 'a' && str[i] <= 'z') {
// dp[i + 1][j] = 1;
// if (str[i] - 32 == sub[j]) {
// dp[i + 1][j + 1] = 1;
// }
// } else {
// if (str[i] == sub[j]) {
// dp[i + 1][j + 1] = 1;
// }
// }
// }
// }
// }
// if (dp[lenstr + 1][lensub + 1]) {
// printf ("YES\n");
// } else {
// printf ("NO\n");
// }
//}
void work () {
memset (dp, 0, sizeof dp);
scanf ("%s%s", str + 1, sub + 1);
int lenstr = strlen (str + 1);
int lensub = strlen (sub + 1);
dp[0][0] = 1;
for (int i = 1; i <= lenstr; ++i) {
dp[i][0] = 1;
}
for (int i = 1; i <= lenstr; ++i) {
for (int j = 1; j <= lensub + 1; ++j) {
if (dp[i - 1][j - 1]) {
if (str[i] >= 'a' && str[i] <= 'z') {
dp[i][j - 1] = 1;
if (str[i] - 32 == sub[j]) {
dp[i][j] = 1;
}
if (str[i] == sub[j]) {
dp[i][j] = 1;
}
} else {
if (str[i] == sub[j]) {
dp[i][j] = 1;
}
}
}
}
}
// printf ("%d\n", dp[5][3]);
if (dp[lenstr][lensub]) {
printf ("YES\n");
} else {
printf ("NO\n");
}
}
int main () {
#ifdef local
freopen("data.txt","r",stdin);
#endif
int t;
scanf ("%d", &t);
while (t--) work ();
return 0;
}
View Code