• [20191005机房测试] Reverse


    小G有一个长度为n的01串T,其中只有TS=1,其余位置都是0。现在小G可以进行若干次以下操作:
    · 选择一个长度为K的连续子串(K是给定的常数),翻转这个子串(左右翻转)
    对于每个 i ∈ [1, n],小G想知道杓少要进行多少次操作使得Ti = 1
    特别的,有m个禁止位置,你要保证在操作过程中 1 始终不在任何一个禁止位置上
    

    原题面很坑……翻转指的是左右翻转而不是异或每个数……
    考场上第一眼以为是Splay或者什么其他的算法,就去看T2T3了
    结果T1一个爆搜就过了???

    代码:

    #include<bits/stdc++.h>
    #define inf 1234567890
    #define N 100005
    using namespace std;
    int n,K,m,S,x;
    int L[N],R[N],dis[N];
    
    template<class T>inline void read(T &res)
    {
    	char c;T flag=1;
    	while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
    	while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
    }
    
    bool vis[N];
    queue<int> q;
    void bfs()
    {
        q.push(S);
        vis[S]=1;
        while(!q.empty())
        {
            int x=q.front();q.pop();
            for(int i=max(1,x-K);i<=min(x,n-K);i++)
            {
                int t=K-x+(i<<1);
                if(t>x)break;
                if(!vis[t]&&dis[t]!=-1)
                {
                    vis[t]=1;
                    dis[t]=dis[x]+1;
                    q.push(t);
                }
                if(dis[t]!=-1)i=max(i,(x+R[t]-K)>>1);
                L[t]=min(L[t],K-x+max(1,x-K)*2);
                R[t]=max(R[t],K-x+min(x,n-K)*2);
            }
            for(int i=min(x,n-K);i>=max(1,x-K);i--)
            {
                int t=K-x+(i<<1);
                if(t<=x)break;
                if(!vis[t]&&dis[t]!=-1)
                {
                    vis[t]=1;
                    dis[t]=dis[x]+1;
                    q.push(t);
                }
                if(dis[t]!=-1)i=min(i,(x+L[t]-K)>>1);
                L[t]=min(L[t],K-x+max(1,x-K)*2);
                R[t]=max(R[t],K-x+min(x,n-K)*2);
            }
        }
    }
    
    int main()
    {
    	freopen("reverse.in","r",stdin);
    	freopen("reverse.out","w",stdout); 
    	read(n);read(K);read(m);read(S);
        K--;
        for(register int i=1;i<=N-5;++i) dis[i]=inf;
    	dis[S]=0;
        for(register int i=1;i<=n;++i) L[i]=R[i]=i;
        while(m--)
        {
        	read(x);
            dis[x]=-1;
        }
        bfs();
        for(register int i=1;i<=n;++i)
        {
            if(dis[i]==inf) printf("-1 ");
            else printf("%d ",dis[i]);
        }
        return 0;
    }
    
    
    
  • 相关阅读:
    LeetCode38 报数
    序列化和反序列化
    JAVA 正则表达式
    Comparable接口和Comparator接口
    IO流-输入输出的简单实例
    JAVA File类
    URI, URL, URN
    web自动化测试第2步:定位元素
    web自动化测试第1步:配置基于python语言的自动化测试环境
    使用webdriver扒取网站小说(一)-----基础篇
  • 原文地址:https://www.cnblogs.com/tqr06/p/11625392.html
Copyright © 2020-2023  润新知