【2019.10.27】
T1是道睿智题,理解题意花了20min,出题人的样例给了相当没给,用自己的话翻译了下题面后发现没注意到a1也可以更改,于是就想到了读入时线型预处理下每组等差数列,结构体记下末尾的序号、编号和数列长度;再枚举数列,合并算len,ans就是max(ans,ans+len);
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define ri register int #define ll long long #define For(i,l,r) for(ri i=l;i<=r;i++) #define Dfor(i,r,l) for(ri i=r;i>=l;i--) using namespace std; const int M=1e5+5; int n,k,a[M],ans,cnt=1,vis[M],len; struct node{ int x,e,l; }f[M]; inline ll read(){ ll f=1,sum=0; char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){sum=(sum<<1)+(sum<<3)+(ch^48);ch=getchar();} return f*sum; } int main(){ freopen("chess.in","r",stdin); freopen("chess.out","w",stdout); n=read(),k=read(); For(i,1,n){ a[i]=read(); if((i>1)&&(a[i]-a[i-1]==k)){ f[cnt].l++; } else{ if(f[cnt].l) f[cnt].x=i-1,f[cnt].e=a[i-1],f[cnt].l++,cnt++; } } if(f[cnt].l) f[cnt].x=n,f[cnt].e=a[n],f[cnt].l++; else cnt--; For(i,1,cnt){ //cout<<f[i].x<<" "<<f[i].e<<" "<<f[i].l<<endl; if(!vis[i]){ vis[i]=1;len=f[i].l; for(ri j=i+1;j<=cnt;j++,!vis[j]){ if(f[j].e-f[i].e==(f[j].x-f[i].x)*k){ vis[j]=1; len+=f[j].l; } } } ans=max(ans,len); } if(!ans) ans=1; printf("%d",n-ans); return 0; }
T2题目好懂,but从我做的少的可怜的字符串题来看十分不可做。题意就是问一串字符中有多少子串位移后不改变原串(然而我没总结出来)。最简单的枚举需要对string函数比较了解(std我也够菜),正解我也不太可(KMP和哈希忘干净了...赶紧刷题)
简单暴力:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define ri register int #define ll long long #define For(i,l,r) for(ri i=l;i<=r;i++) #define Dfor(i,r,l) for(ri i=r;i>=l;i--) using namespace std; string a,b,s,p; int sum,len; inline ll read(){ ll f=1,sum=0; char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){sum=(sum<<1)+(sum<<3)+(ch^48);ch=getchar();} return f*sum; } int main(){ freopen("substring.in","r",stdin); freopen("substring.out","w",stdout); cin>>s; len=s.size(); For(i,1,len){ For(j,i,len){ b=s; a=s.substr(i-1,j-i+1); b.erase(i-1,j-i+1); int slen=b.size(); For(k,0,slen){ p=b; p=p.insert(k,a); if(p==s) sum++; } } } printf("%lld",sum); return 0; }
%正%解%(先嫖上):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> #define up(__i,__start,__end) for (int __i = (__start); __i <= (__end); __i++) #define down(__i, __start,__end) for (int __i = (__start); __i >= (__end); __i--) typedef long long ll; typedef unsigned long long ull; template<typename T> inline bool cmax(T &a, T b) {return a < b ? a = b, 1 : 0;} template<typename T> inline bool cmin(T &a, T b) {return a > b ? a = b, 1 : 0;} const ull bs = 17171; const int maxn = 6e3 + 5; int n, cnt[maxn], f[maxn][maxn]; char s[maxn]; ull h[maxn], pw[maxn]; inline ull hit(int cl, int cr) {return h[cr] - h[cl - 1] * pw[cr - cl + 1];} int main() { freopen("substring.in", "r", stdin); freopen("substring.out", "w", stdout); scanf("%s", s + 1); n = std::strlen(s + 1); pw[0] = 1; up (i, 1, n) pw[i] = pw[i - 1] * bs, h[i] = h[i - 1] * bs + s[i]; ll ans = 0; up (len, 1, n) { up (i, 0, n) cnt[i] = 0; up (i, len, n) { cnt[i] = 1; if (i - len * 2 >= 0) cnt[i] += hit(i - len + 1, i) == hit(i - len - len + 1, i - len) ? cnt[i - len] : 0; cmax(f[i - cnt[i] * len + 1][i], cnt[i]); } } up (i, 1, n) down (j, n, i) { cmax(f[i][j], 1); int len = (j - i + 1) / f[i][j]; if (i + len <= j) cmax(f[i + len][j], f[i][j] - 1); if (j - len >= i) cmax(f[i][j - len], f[i][j] - 1); ans += 1 + (f[i][j] - 1) * 2; } printf("%lld\n", ans); return 0; }
T3题都没读懂搞好久,不如去搞T2,所以一题不花太长时间,一种思路不花太长时间。题解也没解释样例,依旧不懂。