https://vpn.bupt.edu.cn/http/10.105.242.80/problem/p/94/
用set大法写了一堆自己都看不懂的代码, 一提交居然AC了, 一发入魂
堪比DP的set大法
#include <bits/stdc++.h>
#define FF(a,b) for(int a=0;a<b;a++)
#define F(a,b) for(int a=1;a<=b;a++)
#define LEN 510000
#define INF 1000000
#define bug(x) cout<<#x<<"="<<x<<endl;
using namespace std;
char buf[100010];
int main()
{
// freopen("./in","r",stdin);
int N;
scanf("%d",&N);
while(N--){
scanf("%s",buf);
int n;
scanf("%d",&n);
int len=strlen(buf);
set<int> pos[26]; //记录某一字母所在的所有位置
FF(i,len){
pos[buf[i]-'a'].insert(i);
}
while(n--){
char op[20];
char data[20];
scanf("%s%s",op,data);
if(strcmp(op,"INSERT")==0){
buf[len]=data[0];
pos[buf[len]-'a'].insert(len);//维护
len++;
buf[len]=0;
}else{
int p;
int ans;
sscanf(data,"%d",&p);
char c=buf[p];
set<int>& tpos=pos[c-'a'];
set<int>::iterator it=tpos.find(p);
if(it==tpos.end()){ //找不到
ans=-1;
}
else if(tpos.size()==1){ //只记录了找到的一个
ans=-1;
}
else{
it++;
ans=INF;
if(it!=tpos.end()){
ans=*it-p;
}
it--;//复原
if(it!=tpos.begin()){
it--;
if( (p-*it)<ans){
ans=(p-*it);
}
}
}
printf("%d\n",ans);
}
}
}
return 0;
}
动态规划
其实DP也简单.
对于录入的数据, 从左到有做如下状态转移:
- 用pre[k] 记录 字母k最近(最靠右)出现的下标. 未出现用0代替
- 对字符串从左到右扫描, 当前下标为i , 字符为k, 做判断 :
- 如果pre[k]首次出现
pre[k] = i; //仅仅做更新
- 如果pre[k]不是首次出现
j=pre[k] //记录上次位置
pre[k] = i; //做更新
f[i]=i-j; //因为i是最近(右)出现的, 必然距离左边的那个字母最近
f[j]=min(f[j],f[i]) //而左边的, 需要状态转移
欧阳巨佬代码:
// #include <bits/stdc++.h>
#include<cstdio>
#include<iostream>
#include<vector>
#include<map>
#include<queue>
#include<algorithm>
#include<deque>
#include<cmath>
#include<set>
#include<cstring>
#include<string.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
//----------------
#define int long long
#define double long double
//----------------
#define file(s) freopen(s ".in", "r", stdin), freopen(s ".out", "w", stdout)
inline int read()
{
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9')
{
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
{
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
#define sdf(x) x=read()
#define For(i, a, b) for (int i = (a); i <= (b); i++)
#define FFor(i, a, b) for (int i = (a); i >= (b); i--)
#define me(a, b) memset(a, b, sizeof(a))
#define addmod(x, y) (x) = ((x)+ (y)) % mod
#define mulmod(x, y) (x) = (((x) % mod) * ((y) % mod)) % mod
#define chkmin(x, y) (x) = (x) <= (y) ? (x) : (y)
#define chkmax(x, y) (x) = (x) >= (y) ? (x) : (y)
#define mid ((l + ((r - l)/2)))
#define Edge struct edge{int to, nx, w;}e[N << 1];int fi[N];int ce = 1;
#define star_link inline void add(int u, int v, int w){e[++ce] = (edge){v, fi[u], w};fi[u] = ce;}
#define Qmul inline ll qmul(ll x,ll y){ll ans=1;for(;y;y>>=1,mulmod(x,x))if(y&1)mulmod(ans,x);return ans;}
#define Go(u) for (int i = fi[u]; i; i = e[i].nx)
#define random(a, b) ((a) + rand() % ((b) - (a) + 1))
#define cnm cout<<"d"
#define bg1(x) cout<<(#x)<<":"<<(x)<<" "<<endl
#define bg2(x,y) cout<<(#x)<<":"<<(x)<<" "<<(#y)<<":"<<(y)<<" "<<endl
#define bg3(x,y,z) cout<<(#x)<<":"<<(x)<<" "<<(#y)<<":"<<(y)<<" "<<(#z)<<":"<<(z)<<" "<<endl
#define bg4(x,y,z,w) cout<<(#x)<<":"<<(x)<<" "<<(#y)<<":"<<(y)<<" "<<(#z)<<":"<<(z)<<" "<<(#w)<<":"<<(w)<<" "<<endl
#define bg5(x,y,z,w,k) cout<<(#x)<<":"<<(x)<<" "<<(#y)<<":"<<(y)<<" "<<(#z)<<":"<<(z)<<" "<<(#w)<<":"<<(w)<<" "<<(#k)<<":"<<(k)<<" "<<endl
int die = 0;
#define Die die++;if(die>100000){cout<<"dead!!!";exit(0);}
#define lson p << 1, l, mid
#define rson p << 1 | 1, mid + 1, r
#define root 1, 1, n
const double eps = 1e-9;
// srand((unsigned)time(NULL));
ll mod = 1e9 + 7;
const int N = 1e6 + 5;
int T;
char s[N], ss[N];
int q;
char c;
int n;
int f[N];
int pre[N];
void wk(int i) {
f[i] = inf;
int k=s[i] - 'a';
int j = pre[k];
if (!pre[k])
pre[k] = i;
else {
f[i] = i - j;
pre[k] = i;
f[j]=min(f[j],i-j);
}
}
void wk2(int i) { //这个是我阅读巨佬代码后做的优化, 减少代码量, 逻辑与wk等效
f[i] = inf;
int k=s[i] - 'a';
int j = pre[k];
if(pre[k]) {
f[i] = i - j;
f[j]=min(f[j],i-j);
}
pre[k] = i;
}
signed main()
{
freopen("in","r",stdin);
sdf(T);
while (T--) {
scanf("%s", s + 1);
n = strlen(s + 1);
sdf(q);
For(i, 0, 25)pre[i] = 0;
For(i, 1, n) {
wk(i);
}
while (q--) {
scanf("%s", ss + 1);
if (ss[1] == 'I') {
scanf(" %c", &c);
s[++n] = c;
wk(n);
} else {
int x;
sdf(x);
x++;
if (f[x] == inf)printf("-1\n");
else printf("%lld\n", f[x]);
}
}
}
}