2024SMUSpring天梯2补题

L2-2:红色警报

题意:

只要连通块数目减少就输出RedAlert,主要是连通块数目..

int n,m,k;
unordered_map<int,int> mark;
vector<int> vct[505];
bool vis[505];
void dfs(int x){
    for(auto v:vct[x]){
        if(!vis[v]&&!mark[v]){
            vis[v]=1;
            dfs(v);
        }
    }
}
void solve(){                   //L2-2      ??---
    // 题意理解错了,不是现有国家整体从连通到不连通才输出RedAlert。而是只要国家连通块增加了,就输出RedAlert..
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        int u,v;
        cin>>u>>v;
        vct[u].emplace_back(v);
        vct[v].emplace_back(u);
    }
    cin>>k;
    int cntBlock=0;
    for(int i=0;i<n;i++) {
        if(!vis[i]){
            vis[i]=1;
            dfs(i);
            cntBlock++;
        }
    }
    for(int i=1;i<=k;i++){
        int bd; cin>>bd;
        mark[bd]=1;
        memset(vis,0,sizeof(vis));
        int curcnt=0;
        for(int j=0;j<n;j++){
            if(!vis[j]&&!mark[j]){
                dfs(j);
                vis[j]=1;
                curcnt++;
            }
        }
        if(curcnt<=cntBlock) cout<<"City "<<bd<<" is lost."<<endl;
        else cout<<"Red Alert: City "<<bd<<" is lost!"<<endl;
        cntBlock=curcnt;
    }
    if(k==n) cout<<"Game Over.";
}

L2-3:排座位

题意:

朋友关系可以传递,敌对关系不可以传递。

int fa[300];//1-100存朋友关系.101-200存敌对关系.---no!!敌对关系不会传递!!
int find(int x){
    if(x!=fa[x]) fa[x]=find(fa[x]);
    return fa[x];
}
void Union(int x,int y){
    int fa1=find(x),fa2=find(y);
    fa[fa1]=fa2;
}
void solve(){                       //L2-3
    //要用并查集,用map写的话只有22分,扣3分。。因为长的传递关系map识别不出来..
    int n,m,k;
    cin>>n>>m>>k;
    for(int i=1;i<=100;i++) fa[i]=i;
    unordered_set<int> hate[105];
    for(int i=1;i<=m;i++){
        int u,v,rela;
        cin>>u>>v>>rela;
        if(rela==-1){
            hate[u].insert(v);   //一个人敌对的人可能有多个
            hate[v].insert(u);
        }
        else if(find(u)!=find(v)) Union(u,v);
    }
    while(k--){
        int u,v; cin>>u>>v;
        int frdu=find(u),frdv=find(v);
        if((hate[u].find(v)!=hate[u].end())&&frdu==frdv) cout<<"OK but..."<<endl;
        else if(hate[u].find(v)!=hate[u].end()) cout<<"No way"<<endl;
        else if(frdu==frdv) cout<<"No problem"<<endl;
        else cout<<"OK"<<endl;
    }
}

L3-1:肿瘤诊断

题意:

题目的实现不难,三维bfs即可.但是一开始没理解图是怎么样的。如图所示,在某一个1的位置,即蓝色的位置。图可以通向上一层,和下一层,以及该层的东南西北,6个方向的1.题意就是数出这些连通块的1,大于等于t的才记录到ans.(即输入是一片一片从上往下输入的,每一片是m*n的,一共有L片)

int n,m,l,t,ans=0;
int maze[65][1300][130];    //三维的,有上,下,东南西北,6个方向
bool vis[65][1300][130];
typedef struct myp{
    int f,xx,yy;
}myp;
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
void bfs(int f,int x0,int y0){
    int cnt=0;
    vis[f][x0][y0]=1;
    queue<myp> que;
    que.emplace(myp{f,x0,y0});
    while(que.size()){                          //看清楚ff和f...
        int ff=que.front().f,xx=que.front().xx,yy=que.front().yy;
        que.pop();
        cnt++;
        if(ff-1>=1&&maze[ff-1][xx][yy]==1&&!vis[ff-1][xx][yy]) que.emplace(myp{ff-1,xx,yy}),vis[ff-1][xx][yy]=1;    //记得标记vis
        if(ff+1<=l&&maze[ff+1][xx][yy]==1&&!vis[ff+1][xx][yy]) que.emplace(myp{ff+1,xx,yy}),vis[ff+1][xx][yy]=1;
        for(int i=0;i<4;i++){
            int x=xx+dx[i],y=yy+dy[i];
            if(x>=1&&x<=n&&y>=1&&y<=m&&maze[ff][x][y]==1&&!vis[ff][x][y]){
                que.emplace(myp{ff,x,y});           
                vis[ff][x][y]=1;
            }
        }
    }
    if(cnt>=t) ans+=cnt;
}
void solve(){                   //L3-1   三维的bfs,不难
    cin>>n>>m>>l>>t;
    for(int f=1;f<=l;f++){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                cin>>maze[f][i][j];
            }
        }
    }
    for(int f=1;f<=l;f++){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(!vis[f][i][j]&&maze[f][i][j]==1){
                    bfs(f,i,j);
                }
            }
        }
    }
    cout<<ans;
}

L3-3:特殊堆栈

题意:

思路:普通的两个优先队列对顶堆,不好实现删除操作。这题可以用两个multiset来维护数据,模拟对顶堆。也容易进行删除操作。就是有点绕,看清楚想明白就好。

void solve(){                   //补L3-3 特殊堆栈
    int n; cin>>n;
    stack<int> stk;
    multiset<int> mstbig,mstless;   //模拟大根堆和小根堆
    while(n--){
        string str; cin>>str;
        if(str=="Pop"){                //维护对顶堆的删除
            if(stk.size()==0) cout<<"Invalid"<<endl;
            else {
                if(mstless.size()==mstbig.size()){
                    if(mstless.find(stk.top())!=mstless.end()){
                        mstless.erase(mstless.find(stk.top()));
                        mstless.emplace(*mstbig.rbegin());
                        mstbig.erase(mstbig.find(*mstbig.rbegin()));
                    }
                    else mstbig.erase(mstbig.find(stk.top()));
                }
                else if(mstless.size()>mstbig.size()){
                    if(mstless.find(stk.top())!=mstless.end()) mstless.erase(mstless.find(stk.top()));
                    else{
                        mstbig.erase(mstbig.find(stk.top()));
                        mstbig.emplace(*mstless.begin());
                        mstless.erase(mstless.find(*mstless.begin()));
                    }
                }
                cout<<stk.top()<<endl;
                stk.pop();
            }
        }
        else if(str=="PeekMedian"){
            if(stk.size()==0) cout<<"Invalid"<<endl;
            else if(mstless.size()==mstbig.size()) cout<<*mstbig.rbegin()<<endl;   //n/2位置
            else cout<<*mstless.begin()<<endl; //(n+1)/2位置
        }
        else{               //带删除元素操作的对顶堆维护
            int x;cin>>x;
            stk.emplace(x);
            if(mstless.size()==0&&mstbig.size()==0) mstless.emplace(x);
            else if(mstless.size()==mstbig.size()){         //两个堆大小相同-
                if(x>=*mstbig.rbegin()) mstless.emplace(x);   //大根堆size不可能为0
                else{
                    mstless.emplace(*mstbig.rbegin());
                    mstbig.erase(mstbig.find(*mstbig.rbegin()));
                    mstbig.emplace(x);
                }
            }
            else if(mstless.size()>mstbig.size()){     //小根堆多一个,一定只是多一个,是维护出来的
                if(x<=*mstless.begin()) mstbig.emplace(x);    //小根堆size不可能为0
                else{
                    mstbig.emplace(*mstless.begin());
                    mstless.erase(mstless.find(*mstless.begin()));
                    mstless.emplace(x);
                }
            }
        }
    }
}

 

 

posted @ 2024-03-27 10:10  osir  阅读(1)  评论(0编辑  收藏  举报