题目链接:https://codeforces.com/contest/1624/problem/E
题目大意
对于每一组样例,给出 n 个长度为 m 的数字串和一个目标串 s。
问:是否可以在 n个数字串中找到诺干个长度大于等于 2 的片段构成目标串 s。
思路
总所周知,任何大于等于
2
2
2 的数字
n
u
m
num
num 都有,
n
u
m
=
2
∗
x
+
3
∗
y
num = 2*x + 3*y
num=2∗x+3∗y。
由上可以知,如果存在合法的组成方式,最后一定可以分为诺干个长度为 2 的片段和若干个长度为 3 的片段。
先存下来所有长度为 2 和 3 的片段,再 dfs 搜一下(注意标记,重复搜会TLE)。
ACcode
#include<bits/stdc++.h>
#define ll long long
#define endl "\n"
using namespace std;
typedef struct Node{
int l, r;
int id;
} node;
node z[150][150][150];
bool v[150][150][150];
vector<vector<int> > res;
vector<vector<int> > ans;
char s[1005];
char a[1005][1005];
int n, m;
int flag;
int dp[1005];
void dfs(int ind){
if(dp[ind]) return;
if(flag) return;
if(ind == m){
flag = 1;
ans = res;
return;
}
if(ind+1 < m && v['9'+1][s[ind]][s[ind+1]]){
int l = z['9'+1][s[ind]][s[ind+1]].l;
int r = z['9'+1][s[ind]][s[ind+1]].r;
int id = z['9'+1][s[ind]][s[ind+1]].id;
res.push_back({l+1, r+1, id});
dfs(ind+2);
res.pop_back();
}
if(ind+2 < m && v[s[ind]][s[ind+1]][s[ind+2]]){
int l = z[s[ind]][s[ind+1]][s[ind+2]].l;
int r = z[s[ind]][s[ind+1]][s[ind+2]].r;
int id = z[s[ind]][s[ind+1]][s[ind+2]].id;
res.push_back({l+1, r+1, id});
dfs(ind+3);
res.pop_back();
}
dp[ind] = 1;
}
int main(){
int ncase;
scanf("%d", &ncase);
while(ncase--){
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; i++) scanf("%s", a[i]);
scanf("%s", s);
for(int i = 1; i <= n; i++){
for(int j = 0; j < m; j++){
if(j+1 < m){
z['9'+1][a[i][j]][a[i][j+1]] = {j, j+1, i};
v['9'+1][a[i][j]][a[i][j+1]] = 1;
}
if(j+2 < m){
z[a[i][j]][a[i][j+1]][a[i][j+2]] = {j, j+2, i};
v[a[i][j]][a[i][j+1]][a[i][j+2]] = 1;
}
}
}
flag = 0;
dfs(0);
if(flag){
cout << ans.size() << endl;
for(auto i : ans){
for(auto j : i) cout << j << " ";
cout << endl;
}
}
else cout << "-1" << endl;
memset(v, 0, sizeof(v));
memset(dp, 0, sizeof(dp));
res.clear();
}
return 0;
}