zoukankan      html  css  js  c++  java
  • NOIP 模拟 1005

    reverse

    给出一个长度为n的01序列,只有s位置为1,其余为0.

    可以通过选择一个长度为k的序列进行翻转,对于每个位置求出至少多少次能够成为1.

    有m个位置在任何时候都不能为1。

    对于所有数据,有1 <=n <=105; 1 <= S; k <= n; 0 <= m <= n.

    保证S不是禁止位置,但禁止位置可能有重复。

    题解

    一开始看成区间取反了。。。

    可以看出就是最短路,而且边权为1,所以可以bfs求。

    但是不可能每次都把区间枚举出来,所以考虑优化。

    对于左端点在i的区间,x能翻到的位置是2*i+k-x-1

    所以发现能到的位置奇偶性相同且连续,所以想到原来用到的一种方法:并查集

    将用过的位置y连向y+2,下次就不会找到他。

    边界是真的难受

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    const int maxn=100005;
    int n,m,k,s;
    int fa[maxn],dis[maxn];
    bool no[maxn];
    
    template<class T>inline void read(T &x){
        x=0;int f=0;char ch=getchar();
        while(!isdigit(ch)) {f|=(ch=='-');ch=getchar();}
        while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
        x = f ? -x : x ;
    }
    
    int find(int x){return fa[x]==x ? x : fa[x]=find(fa[x]);}
    
    void bfs(){
        queue<int> q;
        memset(dis,-1,sizeof(dis));
        dis[s]=0;
        q.push(s);
        while(!q.empty()){
            int x=q.front();
            q.pop();
            int y,r;
            if(x-k+1<0) y=find(k+1-x);
            else y=find(x-k+1);
            if(x+k-1>n) r=2*n-k-x+1;
            else r=x+k-1;
            for(;y<=r;y=find(y+2)){
              if(dis[y]==-1&&!no[y]){//no不判好像也行 
                  dis[y]=dis[x]+1;
                  q.push(y);
                  fa[y]=find(y+2);
                }
            }
        }
    }
    
    int main(){
        freopen("reverse.in","r",stdin);
        freopen("reverse.out","w",stdout);
        read(n);read(k);read(m);read(s);
        for(int i=1;i<=n+2;i++) fa[i]=i;
        for(int i=1;i<=m;i++){
            int x;read(x);
            if(!no[x]) no[x]=true,fa[x]=find(x+2);
        }
        bfs();
        for(int i=1;i<=n;i++) printf("%d ",dis[i]);
    }
    reverse

    还有线段树建边或者set维护也行。


    Silhouette


     

    seat

  • 相关阅读:
    开源电话交换平台FreeSwitch的安装与配置
    快速编辑 Shell 命令行
    RedHat在字符模式下安装图形界面
    Linux字符界面切换到图形界面
    row cache lock
    cursor: pin S
    Excel 2010高级应用-气泡图(八)
    JDBC异常之数据库表不存在
    java.sql.SQLException之数组越界
    java中JDBC报错(一)
  • 原文地址:https://www.cnblogs.com/sto324/p/11625944.html
Copyright © 2011-2022 走看看