10.28测试

T1 眼镜

Sol
一次转换子串显然其内部的答案不会造成影响。所以实际贡献就在转换的边界形成差异。而一次转换有两个边界,至多造成两个差异,所以直接从左往右扫一遍,与上一位相异则\(ans++\),否则\(cnt++\),最后答案就是\(ans+min(2,cnt)\)
Code

#include<bits/stdc++.h>
using namespace std;
const int maxn=500010;
namespace io
{
    inline int read()
    {
        int x=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=0;c=getchar();}
        while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c&15),c=getchar();
        return f?x:-x;
    }
    inline void print(int x)
    {
        static int s[20],len=0;
        if(x<0)putchar('-'),x=-x;
        if(x==0)
        {
            putchar('0');return;
        }
        while(x)
        {
            s[++len]=x%10;
            x/=10;
        }
        for(int i=len;i;i--)putchar(s[i]+'0');
        return;
    }
}
char s[maxn];
int l,ans,cnt;
int main()
{
    freopen("glasses.in","r",stdin);
    freopen("glasses.out","w",stdout);
    using namespace io;
    scanf("%s",s+1);l=strlen(s+1);
    ans=1;
    for(int i=2;i<=l;i++)
    {
        if(s[i]==s[i-1])cnt++;
        else ans++;
    }
    ans+=min(2,cnt);
    print(ans);putchar('\n');
    return 0;
}

T2 FSN

Sol
因为\(f[i]\)很小,直接枚举跑完全背包算每个兵用魔法杀死的花费。然后再把花费拿来和W跑01背包即可。
Code

#include<bits/stdc++.h>
using namespace std;
const int maxn=3010;
namespace io
{
    inline int read()
    {
        int x=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=0;c=getchar();}
        while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c&15),c=getchar();
        return f?x:-x;
    }
    inline void print(int x)
    {
        static char s[20],len=0;
        if(x<0)putchar('-'),x=-x;
        if(x==0)
        {
            putchar('0');return;
        }
        while(x)
        {
            s[++len]=x%10;
            x/=10;
        }
        for(int i=len;i;i--)putchar(s[i]+'0');
        return;
    }
}
int n,m,w;
int g[maxn],k[maxn],l[maxn],f[maxn],t[maxn],ans[maxn];//法伤、法费、血量、法抗、物费 
long long len,dp[maxn],sum;
int co[maxn][20];
inline void pre()
{
    memset(co,0x3f,sizeof(co));
    for(int i=0;i<=10;i++)co[0][i]=0;
    for(int gpc=0;gpc<=10;gpc++)
    {
        for(int i=1;i<=m;i++)
        {
            if(g[i]<=gpc)continue;
            int now=g[i]-gpc;
            for(int j=now;j<=2000;j++)
            {
                co[j][gpc]=min(co[j][gpc],co[j-now][gpc]+k[i]);
            }
        }
        for(int i=1999;i>=0;i--)co[i][gpc]=min(co[i][gpc],co[i+1][gpc]);
    }
    for(int i=1;i<=n;i++)ans[i]=co[l[i]][f[i]];
    return;
}
int main()
{
    freopen("fsn.in","r",stdin);
    freopen("fsn.out","w",stdout);
    using namespace io;
    n=read();m=read();w=read();
    memset(ans,0x3f,sizeof(ans));
    for(int i=1;i<=n;i++)
    {
        l[i]=read();f[i]=read();t[i]=read();
    }
    for(int i=1;i<=m;i++)
    {
        k[i]=read();g[i]=read();
    }
    pre();
    for(int i=1;i<=n;i++)
    {
        sum+=ans[i];
        for(int j=w;j>=t[i];j--)
        {
            dp[j]=max(dp[j],dp[j-t[i]]+ans[i]);
        }
    }
    sum-=dp[w];
    if(sum>=1000000000000000000)printf("02145234\n");
    else print(sum),putchar('\n');
    return 0;
}

T3 REWRITE

Sol
每个*就把A串分开,然后对于每个单独的船,依次向后跑寻找第一个合法位置即可,复杂度\(O(n^2)\)
Code(我直接用kmp是有问题的,改成暴力即可,吐槽kmp能得91分还是多测就离谱。)

#include<bits/stdc++.h>
using namespace std;
const int maxn=5010;
char s[maxn],s1[maxn],t[maxn][maxn];
int fail[maxn][maxn],sum,len[maxn],ls,lt;
bool tag[maxn];
inline bool pipei(char x,char y)
{
    if(x==y||x=='#'||y=='#')return 1;
    return 0;
}
inline void getfail(int x)
{
    for(int i=1;i<=len[x];i++)
    {
        int now=fail[x][i];
        while(now&&pipei(t[x][now+1],t[x][i+1])==0)now=fail[x][now];
        if(pipei(t[x][now+1],t[x][i+1]))fail[x][i+1]=now+1;
    }
    return;
}
inline int find(int st,int x)
{
    int now=0;
    if(len[x]==0)return st-1;
    for(int i=st;i<=ls;i++)
    {
        while(now&&pipei(t[x][now+1],s[i])==0)now=fail[x][now];
        if(pipei(t[x][now+1],s[i]))
        {
            now++;
            if(now==len[x])
            {
                return i;
            }
        }
    }
    return -1;
}
int main()
{
//    freopen("rewrite.in","r",stdin);
//    freopen("rewrite.out","w",stdout);
    int T;scanf("%d",&T);
    while(T--)
    {
        scanf("%s%s",s1+1,s+1);ls=strlen(s+1);lt=strlen(s1+1);
        sum=1;len[1]=0;
        for(int i=1;i<=lt;i++)
        {
            if(s1[i]=='*')sum++,len[sum]=0;
            else if(s1[i]=='#')sum++,len[sum]=0,tag[sum]=1;
            else t[sum][++len[sum]]=s1[i];
        }
        for(int i=1;i<=sum;i++)getfail(i);
        int lst=0;bool fagl=0;
        for(int i=1;i<=sum;i++)
        {
            lst=find(lst+1,i);
            if(lst==-1)
            {
                printf("NO\n");
                fagl=1;
                break;
            }
            lst+=tag[i];
            if(lst>ls)
            {
                printf("NO\n");fagl=1;
                break;
            }
        }
        if(!fagl)printf("YES\n");
    }
    return 0;
}
posted @ 2021-10-28 16:58  wwlvv  阅读(34)  评论(0)    收藏  举报