zoukankan      html  css  js  c++  java
  • 8.8模拟赛

    A组

    T1.vode 没有硝烟的战争

    #include<iostream>
    #include<cstdio>
    #include<set>
    
    using namespace std;
    
    inline int rd(){
        int ret=0,f=1;char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c))ret=ret*10+c-'0',c=getchar();
        return ret*f;
    }
    
    const int MAXN=5005;
    
    int n,m,num;
    int a[MAXN],tot;
    
    bool f[MAXN<<1][MAXN];
    
    int main(){
        freopen("vode.in","r",stdin);
        freopen("vode.out","w",stdout);
        n=rd();m=rd();num=rd();
        for(int i=1;i<=n;i++){
            a[i]=rd();
        }
        for(int i=n+m-1;i>=1;i--){
            int sum=0;
            for(int j=m-1;j>=1;j--){
                int k=i%n?i%n:n;
                int nxt=k==n?1:k+1;
                if(a[k]==a[nxt]) f[i][j]=sum>0;
                else f[i][j]=sum==0;
                sum+=f[i+1][j];
                if(j+num<=m) sum-=f[i+1][j+num];
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=num;j++){
                f[i][0]|=f[i][j];
            }
        }
        for(int i=1;i<=n;i++) printf("%d ",f[i][0]?a[i]:a[i]^1);
                
                    
            
        return 0;    
    }
    View Code

    T2.portal 秘密通道

    写了BFS,挂了四个点,有三个完全不知道为什么

    正解是暴力连边跑最短路。

    UPD:存在这样一种情况,先向一个方向射击,再移动到墙边传送,搜索没有考虑这种情况

    9 6
    ######
    #.F..#
    ###..#
    #....#
    #.C..#
    #....#
    #.#.##
    #...##
    ######
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    using namespace std;
    
    const int MAXN=1005;
    
    inline int rd() {
        int ret=0,f=1;
        char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c))ret=ret*10+c-'0',c=getchar();
        return ret*f;
    }
    
    struct Edge {
        int next,to,w;
    } e[MAXN*MAXN*2];
    int ecnt,head[MAXN*MAXN];
    int sx,sy,fx,fy;
    inline void add(int x,int y,int w) {
        e[++ecnt].next = head[x];
        e[ecnt].to = y;
        e[ecnt].w = w;
        head[x] = ecnt;
    }
    
    #define id(x,y) ((x-1)*(m)+(y))
    int n,m;
    
    char a[MAXN][MAXN],s[MAXN];
    int dx[5]= {0,0,-1,0,1};
    int dy[5]= {0,1,0,-1,0};
    
    struct Node {
        int id,w;
        Node(int x=0,int y=0) {
            id=x;
            w=y;
        }
        bool operator<(const Node &rhs)const {
            return w>rhs.w;
        }
    } top;
    bool vis[MAXN*MAXN];
    int dis[MAXN*MAXN];
    priority_queue<Node> Q;
    void dij(int st) {
        memset(dis,0x3f,sizeof(dis));
        memset(vis,0,sizeof(vis));
        dis[st]=0;
        Q.push(Node(st,0));
        while(!Q.empty()) {
            top=Q.top();
            Q.pop();
            int mn=top.w,mnid=top.id;
            if(dis[mnid]!=mn) continue;
            vis[mnid]=1;
            for(int j=head[mnid]; j; j=e[j].next) {
                int v=e[j].to;
                if(dis[v]>mn+e[j].w) {
                    dis[v]=mn+e[j].w;
                    Q.push(Node(v,dis[v]));
                }
            }
        }
    }
    
    int d1[MAXN*MAXN],d2[MAXN*MAXN],d3[MAXN*MAXN],d4[MAXN*MAXN],d[MAXN*MAXN];
    
    int main() {
        n=rd();
        m=rd();
        memset(d,0x3f,sizeof(d));
        for(register int i=1; i<=n; i++) {
            scanf("%s",s+1);
            for(register int j=1; j<=m; j++) {
                a[i][j]=s[j];
                if(s[j]=='C') sx=i,sy=j;
                if(s[j]=='F') fx=i,fy=j;
            }
        }
        int x,y;
        for(int i=2; i<=n-1; i++) {
            for(int j=2; j<=m-1; j++) {
                if(a[i][j]=='#') continue;
                for(int k=1; k<=4; k++) {
                    x=i+dx[k];
                    y=j+dy[k];
                    if(a[x][y]=='#') continue;
    //                if(i==sx&&j==sy) cout<<x<<" "<<y<<" !
    ";
                    add(id(i,j),id(x,y),1);
                }
            }
        }
        for(x=2; x<=n-1; x++) {
            for(y=2; y<=m-1; y++) {
                if(a[x][y]=='#') continue;
                register int j;
                for(j=x; a[j+1][y]!='#'; j++);
                d1[id(x,y)]=id(j,y);
                d[id(x,y)]=min(d[id(x,y)],j-x+1);
                for(j=x; a[j-1][y]!='#'; j--);
                d2[id(x,y)]=id(j,y);
                d[id(x,y)]=min(d[id(x,y)],x-j+1);
                for(j=y; a[x][j+1]!='#'; j++);
                d3[id(x,y)]=id(x,j);
                d[id(x,y)]=min(d[id(x,y)],j-y+1);
                for(j=y; a[x][j-1]!='#'; j--);
                d4[id(x,y)]=id(x,j);
                d[id(x,y)]=min(d[id(x,y)],y-j+1);
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(a[i][j]=='#') continue;
                add(id(i,j),d1[id(i,j)],d[id(i,j)]);
                add(id(i,j),d2[id(i,j)],d[id(i,j)]);
                add(id(i,j),d3[id(i,j)],d[id(i,j)]);
                add(id(i,j),d4[id(i,j)],d[id(i,j)]);
            }
        }
        dij(id(sx,sy));
        if(dis[id(fx,fy)]==0x3f3f3f3f) puts("nemoguce");
        else cout<<dis[id(fx,fy)];
        
    }
    View Code
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<queue>
    
    using namespace std;
    
    inline int rd(){
        int ret=0,f=1;char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c))ret=ret*10+c-'0',c=getchar();
        return ret*f;
    }
    
    const int MAXN=512;
    
    struct Node{
        int x,y,cost;
    }node,top;
    queue<Node> Q;
    
    int n,m;
    char a[MAXN][MAXN],s[MAXN];
    
    int sx,sy;
    int vis[MAXN][MAXN];
    int dx[5]={0,0,-1,0,1};
    int dy[5]={0,1,0,-1,0};
    int main(){
    //    freopen("portal.in","r",stdin);
    //    freopen("portal.out","w",stdout);
        n=rd();m=rd();
        for(register int i=1;i<=n;i++){
            scanf("%s",s+1);
            for(register int j=1;j<=m;j++){
                a[i][j]=s[j];
                if(s[j]=='C') sx=i,sy=j;
            }
        }
        for(register int i=0;i<=n+1;i++)
            a[i][0]=a[i][m+1]='#';
        for(register int i=0;i<=m+1;i++)
            a[0][i]=a[n+1][i]='#';
        node.cost=0;node.x=sx;node.y=sy;
        Q.push(node);vis[sx][sy]=1;
        while(!Q.empty()){
            top=Q.front();Q.pop();
            int x=top.x,y=top.y,nx,ny,cost=top.cost;
    //        cout<<x<<" "<<y<<"  "<<cost<<endl;
            if(a[x][y]=='F') return printf("%d",cost),0;
            bool succ=0;
            for(register int i=1;i<=4;i++){
                if(a[x+dx[i]][y+dy[i]]!='#') continue;
                succ=1;break;
            }
            if(!succ) goto lab;
            register int j;
            for(j=x;a[j+1][y]!='#';j++);
            if(!vis[j][y]) {
                vis[j][y]=node.cost=cost+1;
                node.x=j;node.y=y;
                Q.push(node);
            }
            for(j=x;a[j-1][y]!='#';j--);
            if(!vis[j][y]) {
                vis[j][y]=node.cost=cost+1;
                node.x=j;node.y=y;
                Q.push(node);
            }
            for(j=y;a[x][j+1]!='#';j++);
            if(!vis[x][j]) {
                vis[x][j]=node.cost=cost+1;
                node.x=x;node.y=j;
                Q.push(node);
            }
            for(j=y;a[x][j-1]!='#';j--);
            if(!vis[x][j]) {
                vis[x][j]=node.cost=cost+1;
                node.x=x;node.y=j;
                Q.push(node);
            }
            lab:
            for(register int i=1;i<=4;i++){
                nx=x+dx[i];ny=y+dy[i];
                if(a[nx][ny]=='#') continue;
                if(vis[nx][ny]) continue;
                vis[nx][ny]=node.cost=cost+1;
                node.x=nx;node.y=ny;
                Q.push(node);
                
            }    
        }
        puts("nemoguce");
        return 0;
    }
    70分搜索

    T3.pictionary 城市猎人

    考场枚举了每个点对的连接时间,然后跑最短路..

    连边确实具有连通块的性质,所以可以用并查集维护,但是并不需要可持久化,有个优秀的做法。

    考虑使用按秩合并的并查集,构造出一个并查集树,边权为这两个集合连接的时间,边数是一个调和级数,大概在NlnN的级别,可以暴力建图,而按秩合并的并查集树高稳定在logn级别(树高一层,节点数至少乘以2)

    这样就可以暴力求树上两点的路径上的最大值了。

    #include<iostream>
    #include<cstdio>
    #include<set>
    
    using namespace std;
    
    inline int rd(){
        int ret=0,f=1;char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c))ret=ret*10+c-'0',c=getchar();
        return ret*f;
    }
    
    const int MAXN=100005;
    
    int n,m,q;
    
    int val[MAXN],fa[MAXN],siz[MAXN];
    int fnd(int x){return x==fa[x]?x:fnd(fa[x]);}
    void cat(int x,int y,int t){
        x=fnd(x);y=fnd(y);
        if(x==y) return;
        if(siz[x]<siz[y]) {
            fa[x]=y;val[x]=t;
            siz[y]+=siz[x];
        }else{
            fa[y]=x;val[y]=t;
            siz[x]+=siz[y];
        }
    }
    
    
    set<int> S;
    
    int main(){
    //    freopen("pictionary.in","r",stdin);
    //    freopen("pictionary.out","w",stdout);
        n=rd();m=rd();q=rd();
        for(int i=1;i<=n;i++) fa[i]=i,siz[i]=1;
        for(int i=1;i<=m;i++){
            int tmp=m-i+1;
            for(int j=tmp*2;j<=n;j+=tmp){
                cat(j,j-tmp,i);
            }
        }
        int x,y,sav,ans;
        for(int i=1;i<=q;i++){
            S.clear();ans=0;
            sav=x=rd();y=rd();
            while(x!=fa[x]) S.insert(x),x=fa[x];
            while(!S.count(y)&&y!=fa[y]) ans=max(ans,val[y]),y=fa[y];
            while(sav!=y) ans=max(ans,val[sav]),sav=fa[sav];
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code

    本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9445212.html

  • 相关阅读:
    idea主题更换pycharm/intellij
    随机生成n张扑克牌。
    JAVA生成6个1-8的随机数,要求无重复。
    一道简单 的循环
    linux虚拟机互访
    linux中grep命令
    vi和vim编辑器
    文件压缩打包以及备份
    文件内容查询
    目录相关操作
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9445212.html
Copyright © 2011-2022 走看看