这条题目据说是条思维题。。。一开始直接暴力strncpy结果tle了。算了,总结一下我看过的各种解法,真是长见识了。
第一种是官方给出的题解方法:就是一开始sort,然后按顺序去放置字符串,一开始愣是没看懂啥意思,看了代码才理解。
以下代码链接,看起来感觉存数据的时候贼暴力
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6+100;
string s[maxn];
vector<pair<int,int> >tmp;
int main(void)
{
int n,k,x;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
cin>>s[i]>>k;
for(int j=0;j<k;j++)
{
scanf("%d",&x);
tmp.push_back(make_pair(x,i));
}
}
sort(tmp.begin(),tmp.end());
string ans;
int len = 1;
for(unsigned i = 0;i<tmp.size();i++)
{
int t1 = tmp[i].first,t2 = tmp[i].second;
while(t1>len)
{
ans += 'a';
len++;
}
//len-t1可以避免重复添加
for(unsigned j = len-t1;j<s[t2].length();j++)
{
ans += s[t2][j];
len++;
}
}
cout<<ans<<endl;
return 0;
}
第二种方法也贼神奇,我一开始看了一下,感觉会爆啊。但是人家毕竟都写好博客了,应该是过了的。看完代码可以发现,他是在针对每一个子串的时候进行避免重复赋值的优化。原博客
地址
代码如下
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
#define LL long long
const int INF = 0x3f3f3f3f;
#define MAXN 500
char s[2000006];
char ch[2000005];
int main()
{
int n,m,x;
int tot=0;
scanf("%d",&n);
for(int i=0; i<n; i++)
{
scanf("%s%d",&ch,&m);
int k=strlen(ch);
int t=-INF;
for(int j=0; j<m; j++)
{
scanf("%d",&x);
x--;
tot=max(x+k,tot);
for(int l=max(x,t); l<x+k; l++)
s[l]=ch[l-x];
t=x+k;
}
}
for(int i=0; i<tot; i++)
if(s[i]=='\0')
printf("a");
else
printf("%c",s[i]);
printf("\n");
return 0;
}
第三种方法是我找到的第一个解法,创建了一个nextt数组,用来跳转下标的位置,感觉很不错。原博主给出了两个方法一个是未优化的,一个是用并查集优化的。未优化的据博主所说用了1300+ms,然后我交了一下,只用了700+ms,莫非人品。。。 原博客链接
#include<bits/stdc++.h>
#define eps 1e-9
#define PI 3.141592653589793
#define bs 1000000007
#define bsize 256
#define MEM(a) memset(a,0,sizeof(a))
typedef long long ll;
using namespace std;
const int maxn = 3000000+5;
int f[maxn],nextt[maxn];
char ch[maxn];
int len;
char ans[maxn];
int main()
{
int n,i,t,j,k;
for(i=0;i<3000000;i++)nextt[i]=i+1;
int now=0,maxx=0;
cin>>n;
for(i=0;i<n;i++)
{
getchar();
scanf("%s",ch);
scanf("%d",&len);
int lenn=strlen(ch);
for(j=0;j<len;j++)
{
scanf("%d",&k);
for(int index=k;index<k+lenn;)
{
ans[index]=ch[index-k];
int tt=nextt[index];
if(tt<k+lenn)
nextt[index]=nextt[tt];
index=tt;
}
maxx=max(maxx,lenn+k-1);
}
}
for(i=1;i<=maxx;i++)
{
if(ans[i]==0)
ans[i]='a';
}
ans[maxx+1]=0;
printf("%s\n",ans+1);
return 0;
}