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<<" !\n";
                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\n",ans);
    }
    return 0;
}
View Code

 

posted @ 2018-08-08 19:38  GhostCai  阅读(104)  评论(0编辑  收藏  举报