北大2192题

来源:互联网 发布:淘宝企业店铺要求 编辑:程序博客网 时间:2024/05/16 10:59

 题目连接:http://acm.pku.edu.cn/JudgeOnline/problem?id=2192

 

版本一:直接从结果串中对比原串进行字符的分配,这里存在问题就是对两个串中都存在的字符如果分配错误就会导致整个问题的求解的错误,如测试用例中的cat tree catrtee按照这种方法就无法得到正确结果。这个错误为解题探测到更多的信息!

 

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

#define MAX 200

int main()
{
 freopen("in.txt","r",stdin);

 char str1[MAX],str2[MAX],res[MAX*2];
 int t,i,j,k,l;

 cin >> t;
 l = 1;
 while(l <= t)
 {
  ++l;

  cin >> str1 >> str2 >> res;
  i = j = k = 0;

  while(res[k] != '/0')
  {
   if(res[k] == str1[i])
   {
    ++k,++i;
    continue;
   }
   else if(res[k] == str2[j])
   {
    ++k,++j;
    continue;
   }
   else
    break;
  }

  if(res[k] != '/0')
   printf("Data set %d: no/n",l);
  else
   printf("Data set %d: yes/n",l);
 }
 return 0;
}

 

版本二:直接暴力搜索两个串的所有组合串,结果超时!

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

#define MAX 200

struct Prob
{
 char str1[MAX];
 char str2[MAX];
 char tmp[MAX*2];
 char tar[MAX*2];
 
 int len1;
 int len2;
 int lf;
 int rt;
 bool flag;
 
 void Init()
 {
  len1 = strlen(str1);
  len2 = strlen(str2);

  lf = rt = 0;
  flag = false;
  tmp[len1+len2] = '/0';
 }

 void Work(int cur)
 {
  if(cur == len1 + len2)
  {
   if(strcmp(tmp,tar) == 0)
    flag = true;
  }
  else
  {
   if(!flag)
   {
    if(lf < len1 && rt < len2)
    {
     tmp[cur] = str1[lf];
     ++lf;
     Work(cur+1);
     --lf;

     tmp[cur] = str2[rt];
     ++rt;
     Work(cur+1);
     --rt;
    }
    else if(lf < len1)
    {
     tmp[cur] = str1[lf];
     ++lf;
     Work(cur+1);
     --lf;
    }
    else if(rt < len2)
    {
     tmp[cur] = str2[rt];
     ++rt;
     Work(cur+1);
     --rt;
    }
   }
  }
 }
};

int main()
{
 freopen("in.txt","r",stdin);
 
 Prob pb;
 int i,t;
 cin >> t;
 i = 1;
 while(i <= t)
 {
  cin >> pb.str1 >> pb.str2 >> pb.tar;
  pb.Init();
  pb.Work(0);
  
  if(pb.flag)
   printf("Data set %d: yes/n",i);
  else
   printf("Data set %d: no/n",i);

  ++i;
 }
 return 0;
}

 

版本三:

用动态规划解决,ok[i][j]表示str1长度为i的前缀和str2长度为j的后缀能否组成目标中str中长度为i+j的前缀串

最优子结构是:ok[i][j] = false (ok[i-1][j] == false && ok[i][j-1] == false) 或者true (ok[i-1][j] == true && str1[i] == tar[i+j] || ok[i][j-1] == true && str2[j] == tar[i+j])

边界条件是:ok[0][0] = true;ok[i][0] =( ok[i-1][0] && str1[i] == tar[i] );ok[0][j] = (ok[0][j-1] && str2[j] == tar[j])

#include <iostream>
using namespace std;

#define MAX 201

int main()
{
 freopen("in.txt","r",stdin);
 
 char str1[MAX],str2[MAX],tar[MAX*2];
 bool ok[MAX][MAX];
 int t,tt,i,j,len1,len2;

 str1[0] = str2[0] = tar[0] = 1;
 cin >> t;
 tt = 1;
 while(tt <= t)
 {
  cin >> str1+1 >> str2+1 >> tar+1;
  len1 = strlen(str1+1);
  len2 = strlen(str2+1);

  ok[0][0] = true;
  for(i = 1;i <= len1;++i)
  {
   if(ok[i-1][0] && str1[i] == tar[i])
    ok[i][0] = true;
   else
    ok[i][0] = false;
  }
  for(j = 1;j <= len2;++j)
  {
   if(ok[0][j-1] && str2[j] == tar[j])
    ok[0][j] = true;
   else
    ok[0][j] = false;
  }

  for(i = 1;i <= len1;++i)
  {
   for(j = 1;j <= len2;++j)
   {
    if(ok[i-1][j] && str1[i] == tar[i+j])
     ok[i][j] = true;
    else if(ok[i][j-1] && str2[j] == tar[i+j])
     ok[i][j] = true;
    else
     ok[i][j] = false;
   }
  }

  if(ok[len1][len2])
   printf("Data set %d: yes/n",tt);
  else
   printf("Data set %d: no/n",tt);
  ++tt;
 }
 return 0;
}

原创粉丝点击