poj 2192
题意:给出两串,两串顺序不变看能否组成第三个串。
此题深搜和DP都能解决:
深搜的话需要几个强有力剪枝条件
1、 第三个串最后一个字符要么是串1的最后一个字符,要么是串2的最后一个字符
2、 按照串1的顺序对串3进行搜索,若不匹配则该字符必是串2的下一个字符。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; char first[202],second[202],third[402],Left[401]; int sign[402]; bool flag; int check() { int i,count=0; int k= strlen (third); for (i=0;i<k;i++) if (!sign[i]) Left[count++]=third[i]; Left[count]= '\0' ; if ( strcmp (Left,second)==0) return 1; return 0; } int dfs( int f, int s, int t) { if (f>= strlen (first)) { if (check()) flag= true ; return 0; } if (flag) return 0; if (first[f]==third[s]) { sign[s]=1; if (s< strlen (third)) dfs(f+1,s+1,t); sign[s]=0; } else { if (third[s]!=second[t]) return 0; //剪枝2 } if (!flag && s< strlen (third)) dfs(f,s+1,t+1); return 0; } int main() { int len1,len2,len3,Case,count=0; scanf ( "%d" ,&Case); while (Case--) { count++; flag= false ; scanf ( "%s %s %s" ,first,second,third); memset (sign,0, sizeof (sign)); len1= strlen (first); len2= strlen (second); len3= strlen (third); if (len1+len2!=len3) { printf ( "Data set %d: no\n" ,count); continue ; } if (third[len3-1]!=first[len1-1] && third[len3-1]!=second[len2-1]) // 剪枝1 { printf ( "Data set %d: no\n" ,count); continue ; } dfs(0,0,0); if (flag) printf ( "Data set %d: yes\n" ,count); else printf ( "Data set %d: no\n" ,count); } return 0; } |
若用DP来作先定义res[i][j]=1表示串1前i个字符和串2的前j个字符能组成串3的前i+j个字符,res[i][j]=0则不能。
状态转移方程如下:
Res[i][j]= (third[i+j]==first[i] && res[i-1][j]==1) ||(third[i+j]==second[j]&&res[i][j-1]==1)
#include<iostream> #include<cstdio> #include<cstring> using namespace std; char first[201],second[201],third[401]; int res[201][201]; int init( int n, int m) { int i; for (i=1;i<=m;i++) if (second[i]==third[i]) res[0][i]=1; else break ; for (i=1;i<=n;i++) if (first[i]==third[i]) res[i][0]=1; else break ; return 0; } int dp( int n, int m) { int i,j; for (i=1;i<=n;i++) for (j=1;j<=m;j++) { if (third[i+j]==first[i] && res[i-1][j]) res[i][j]=1; if (third[i+j]==second[j] && res[i][j-1]) res[i][j]=1; } if (res[n][m]) return 1; return 0; } int main() { int n,len1,len2,count=0;; scanf ( "%d" ,&n); while (n--) { count++; scanf ( "%s %s %s" ,first+1,second+1,third+1); len1= strlen (first+1); len2= strlen (second+1); memset (res,0, sizeof (res)); init(len1,len2); if (dp(len1,len2)) printf ( "Data set %d: yes\n" ,count); else printf ( "Data set %d: no\n" ,count); } return 0; } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?