【2019.10.27】

题目 题解

T1是道睿智题,理解题意花了20min,出题人的样例给了相当没给,用自己的话翻译了下题面后发现没注意到a1也可以更改,于是就想到了读入时线型预处理下每组等差数列,结构体记下末尾的序号、编号和数列长度;再枚举数列,合并算len,ans就是max(ans,ans+len);

#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;
} 
View Code

T2题目好懂,but从我做的少的可怜的字符串题来看十分不可做。题意就是问一串字符中有多少子串位移后不改变原串(然而我没总结出来)。最简单的枚举需要对string函数比较了解(std我也够菜),正解我也不太可(KMP和哈希忘干净了...赶紧刷题

简单暴力:

#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;
}
View Code

%正%解%(先嫖上):

#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;

}
View Code

T3题都没读懂搞好久,不如去搞T2,所以一题不花太长时间,一种思路不花太长时间。题解也没解释样例,依旧不懂。

猜你喜欢

转载自www.cnblogs.com/jian-song/p/11748804.html