Abbreviation ---- hackerrank
---恢复内容开始---
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 这样才能把状态一直传递下去
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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; }
posted on 2016-09-03 19:20 stupid_one 阅读(507) 评论(0) 编辑 收藏 举报