hdu1501 Zipper(dfs && dp)
阿新 • • 發佈:2019-01-06
挺不錯的題。第一反應是模擬字串匹配,但第二個樣例就否定了。
str1 = cat, str2 = tree, str = catrtee,當主串匹配到第四個字元t時,問題來了,是匹配第一個的還是第二個的?模擬的話兩個判斷條件會有個順序,但一旦有順序就會導致其中一種匹配不成功,所以換思路。
一種是簡單的深搜,一種是簡單的dp,思路都很清晰。
dfs:
#include <stdio.h> #include <algorithm> #include <string.h> #include <string> #include <iostream> using namespace std; const int N = 1 << 16; const int INF = 1e8; string str1, str2, str; bool pos; int vis[205][205]; void dfs(int s1, int s2, int s) { if(s1 == str1.length() && s2 == str2.length()) { pos = true; return; } if(str1[s1] != str[s] && str2[s2] != str[s]) return; if(vis[s1][s2]) return; if(pos) return; vis[s1][s2] = 1; if(str1[s1] == str[s]) dfs(s1 + 1, s2, s + 1); if(str2[s2] == str[s]) dfs(s1, s2 + 1, s + 1); } int main() { // freopen("in.txt", "r", stdin); int t, n, Case = 1; scanf("%d", &t); while(t --) { cin >> str1 >> str2 >> str; pos = false; memset(vis, 0, sizeof(vis)); dfs(0, 0, 0); if(pos) printf("Data set %d: yes\n", Case ++); else printf("Data set %d: no\n", Case ++); } return 0; }
dp:注意對邊界的處理,初始化條件為主串長度的字元相同即為1,否則為0。由於其是從1開始dp,所以把三個串的首字元也初始化。
#include <stdio.h> #include <algorithm> #include <string.h> #include <string> #include <iostream> using namespace std; const int N = 205; const int INF = 1e8; char str1[N], str2[N], str[N * 2]; int dp[N][N]; int main() { // freopen("in.txt", "r", stdin); int t, n, Case = 1; scanf("%d", &t); while(t --) { scanf("%s%s%s", str1 + 1, str2 + 1, str + 1); str[0] = str1[0] = str2[0] = '0'; // memset(dp, 0, sizeof(dp)); for(int i = 1; i < strlen(str1); i ++) { if(str1[i] == str[i]) dp[i][0] = 1; else dp[i][0] = 0; } for(int i = 1; i < strlen(str2); i ++) { if(str2[i] == str[i]) dp[0][i] = 1; else dp[0][i] = 0; } for(int i = 1; i < strlen(str1); i ++) { for(int j = 1; j < strlen(str2); j ++) { dp[i][j] = ((dp[i - 1][j] && str1[i] == str[i + j]) || (dp[i][j - 1] && str2[j] == str[i + j])); } } if(dp[strlen(str1) - 1][strlen(str2) - 1]) printf("Data set %d: yes\n", Case ++); else printf("Data set %d: no\n", Case ++); } return 0; }