A
思路
在线做,把所有数字添加前缀都变成位数字,从高位到低位维护到trie树中,每次插入一个新的数字之前先在trie树上贪心,分别找最大值和最小值。
代码
#include<bits/stdc++.h>
#define rep(i,st,ed) for(int i=st;i<=ed;++i)
#define bl(u,i) for(int i=head[u];i;i=e[i].nxt)
#define LLM LONG_LONG_MAX
#define LLm LONG_LONG_MIN
#define pii pair<ll,ll>
typedef long long ll;
typedef double db;
using namespace std;
const ll INF=0x3f3f3f3f;
inline void In(ll _,...)
{
va_list lis;
va_start(lis,_);
while(_--)
scanf("%lld",va_arg(lis,ll*));
}
inline void Out(ll _,...)
{
va_list lis;
va_start(lis,_);
while(_--)
printf("%lld\n",va_arg(lis,ll));
}
inline void Out_(ll _,...)
{
va_list lis;
va_start(lis,_);
while(_--)
printf("%lld ",va_arg(lis,ll));
}
const int N=1E6+2;
int n,tot;
int t[20*N][10];
string ans_max="0",ans_min="999999999999999999999";
void dfs_max(string s)
{
int rt=0;
rep(i,0,18)
{
int cur=s[i]-'0',maxi=-1,p=-1;
rep(j,0,9)
{
if(t[rt][j] && (cur+j)%10>maxi)
{
maxi=(cur+j)%10;
p=j;
}
}
if(p==-1 && rt)
{
ans_max=max(ans_max,s);
return;
}
s[i]=maxi+'0';
rt=t[rt][p];
}
ans_max=max(ans_max,s);
}
void dfs_min(string s)
{
int rt=0;
rep(i,0,18)
{
int cur=s[i]-'0',mini=INF,p=-1;
rep(j,0,9)
{
if(t[rt][j] && (cur+j)%10<mini)
{
mini=(cur+j)%10;
p=j;
}
}
if(p==-1 && rt)
{
ans_min=min(ans_min,s);
return;
}
s[i]=mini+'0';
rt=t[rt][p];
}
ans_min=min(ans_min,s);
}
void insert(string s)
{
int rt=0;
rep(i,0,18)
{
int cur=s[i]-'0';
if(!t[rt][cur])
t[rt][cur]=++tot;
rt=t[rt][cur];
}
}
void print(string s)
{
int flag=0;
for(auto k:s)
{
if(k!='0' || flag)
{
flag=1;
cout<<k;
}
}
if(flag==0)
cout<<0;
}
int main()
{
cin>>n;
rep(i,1,n)
{
string s;
cin>>s;
while(s.size()<19)
s='0'+s;
dfs_max(s);
dfs_min(s);
insert(s);
// cout<<i<<" ";print(ans_min);cout<<" ";print(ans_max);
//cout<<endl;
}
print(ans_min);
cout<<" ";
print(ans_max);
cout<<endl;
}
E
思路
设第一个串为串,第二个串为串。二分使用多长的前缀,之后用KMP检查一下匹配数即可。
代码
#include<bits/stdc++.h>
#define rep(i,st,ed) for(int i=st;i<=ed;++i)
#define bl(u,i) for(int i=head[u];i;i=e[i].nxt)
#define LLM LONG_LONG_MAX
#define LLm LONG_LONG_MIN
#define pii pair<ll,ll>
typedef long long ll;
typedef double db;
using namespace std;
const ll INF=0x3f3f3f3f;
inline void In(ll _,...)
{
va_list lis;
va_start(lis,_);
while(_--)
scanf("%lld",va_arg(lis,ll*));
}
inline void Out(ll _,...)
{
va_list lis;
va_start(lis,_);
while(_--)
printf("%lld\n",va_arg(lis,ll));
}
inline void Out_(ll _,...)
{
va_list lis;
va_start(lis,_);
while(_--)
printf("%lld ",va_arg(lis,ll));
}
const ll N=1E5+10;
ll n,m,k;
ll p[N];
string s,t;
void pre()
{
ll j=0;
rep(i,2,m)
{
while(j && t[i]!=t[j+1])
j=p[j];
if(t[i]==t[j+1])
++j;
p[i]=j;
}
}
ll check(ll x)
{
ll j=0,ret=0;
rep(i,1,n)
{
while(j && s[i]!=t[j+1])
j=p[j];
if(s[i]==t[j+1])
++j;
if(j==x)
{
++ret;
j=p[j];
}
}
return ret>=k;
}
void print()
{
rep(i,1,n)
cout<<p[i]<<" ";
cout<<endl;
}
int main()
{
getline(cin,s);
n=s.size();
s=' '+s;
getline(cin,t);
m=t.size();
t=' '+t;
In(1,&k);
pre();
ll l=1,r=m,ans=0;
while(l<=r)
{
ll mid=(l+r)>>1;
if(check(mid))
{
ans=mid;
l=mid+1;
}
else
r=mid-1;
}
if(ans==0)
puts("IMPOSSIBLE");
else
cout<<t.substr(1,ans);
}