经典字符串动态规化题目 013:Zipper

总时间限制: 

1000ms

 

内存限制: 

65536kB

描述

Given three strings, you are to determine whether the third string can be formed by combining the characters in the first two strings. The first two strings can be mixed arbitrarily, but each must stay in its original order.

For example, consider forming "tcraete" from "cat" and "tree":

String A: cat
String B: tree
String C: tcraete

As you can see, we can form the third string by alternating characters from the two strings. As a second example, consider forming "catrtee" from "cat" and "tree":

String A: cat
String B: tree
String C: catrtee

Finally, notice that it is impossible to form "cttaree" from "cat" and "tree".

输入

The first line of input contains a single positive integer from 1 through 1000. It represents the number of data sets to follow. The processing for each data set is identical. The data sets appear on the following lines, one data set per line.

For each data set, the line of input consists of three strings, separated by a single space. All strings are composed of upper and lower case letters only. The length of the third string is always the sum of the lengths of the first two strings. The first two strings will have lengths between 1 and 200 characters, inclusive.

输出

For each data set, print:

Data set n: yes

if the third string can be formed from the first two, or

Data set n: no

if it cannot. Of course n should be replaced by the data set number. See the sample output below for an example.

样例输入

3
cat tree tcraete
cat tree catrtee
cat tree cttaree

样例输出

Data set 1: yes
Data set 2: yes
Data set 3: no

来源

Pacific Northwest 2004

 

这道题目的中文版本是

【不可使用本地IDE】字符串插入

给出3个字符串s1,s2,s3,判断s3是否是由s1和s2相互插入而成。

举个例子:

s1="adbcaa"

s2="acabca"

当 s3="adbacacabcaa", return true.

当 s3="adbacacabacc", return false.

bool isInterleave(string s1, string s2, string s3) { 

}

 

用动态规化的做法,记dp[i][j] 表示状态s1的前i个字符,和s2的前j个字符,是否能构成s3的前i+j个字符,要特别注意,在dp中下标从1开始,边界条件有dp[0][0] = 1

代码

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

bool zip(string &a, string &b, string &c) 
{
	// dp[i][j] 表示A中前i个字符串,与B中前j个字符串,是否能构成C中前i+j个字符串
	int n = a.size();
	int m = b.size();
	vector<vector<bool>> dp(n+1, vector<bool>(m+1, false));
	dp[0][0] = true;
	for (int i = 0; i <= n; i++) {
		for (int j = 0; j <= m; j++) {
			if (i>=1&& dp[i - 1][j] && a[i - 1] == c[i + j - 1])
				dp[i][j] = true;
			if (j>=1 && dp[i][j - 1] && b[j - 1] == c[i + j - 1])
				dp[i][j] = true;
		}
	}
	return dp[n][m];

}

int main()
{
	int n;
	cin >> n;
	for(int i=1;i<=n;i++) {
		string str1, str2, str3;
		cin >> str1 >> str2 >> str3;
		if (zip(str1, str2, str3))
			cout << "Data set " << i << ": " << "yes" << endl;
		else
			cout << "Data set " << i << ": " << "no" << endl;
	}

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值