• ICPC2017南宁站题解(A,E,F,H,I,J,L,M)


    VP比赛时间:2020-07-23: 7 / 13   Rank: 35 / 228

    VP通过:A,E,F,H,I,J,L

    赛后补题:M

    感想:这场对大数要求挺多(2道题F和L),我队Java选手很给力。然后银牌题大概是E和M(M那时候没信心去挑战毕竟在银首,但是赛后补题发现是一个floyd+裸最大独立集,还是简单题。E是偏向思维的概率数学)。H是大模拟,I题是无脑dfs模拟。就这场和icpc2019南昌来说,我感觉银牌图论题可能要求并不是很高,要有信心去挑战银牌题吧。毕竟感觉铜牌图论撑死就是生成树和最短路了(真的吗?)

    A.Abiyoyo

    第一签到题,Anonytt,懒得说:

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,n) for(int i=a;i<=n;i++)
    #define per(i,n,a) for(int i=n;i>=a;i--)
    #define endl '
    '
    #define eps 0.000000001
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define IO ios::sync_with_stdio(false);cin.tie(0);
    using namespace std;
    const int INF=0x3f3f3f3f;
    const ll inf=0x3f3f3f3f3f3f3f3f;
    const int mod=1e9+7;
    const int maxn=1e5+5;
    int main(){
        int T;cin>>T;
        while(T--){
            int n;cin>>n;
            rep(i,1,n){
                puts("Abiyoyo, Abiyoyo.");
            }
            rep(i,1,2){
                puts("Abiyoyo, yo yoyo yo yoyo.");
            }
        }
    }
    View Code

    E. The Champion

    银牌题,Libm,我不会。

    #include <bits/stdc++.h>
    #define ll unsigned long long
    #define endl '
    '
    using namespace std;
    double p; 
    ll fa[65];
    double cal(int r,ll k){
        double ans=1;
        if(r==1){
            if(k==1) ans=1;
            else ans=1-p;
        }
        else if(k<=fa[r-1]){
            double cur=1;
            while(k<=fa[r-1]){
                cur=cur*p;
                r--;
                if(r==1) break;
            }
            ans=(1-p)+p-cur+cur*cal(r,k);
        }
        else{
            while(k>fa[r-1]){
                k-=(fa[r-1]);
                r--;
                ans*=(1-p);
                if(r==1) break;
            } 
            ans*=cal(r,k);
        } 
        return ans;
    }
    double solve(int r,ll k){
        double ans=1;
        if(r==1){
            if(k==1) ans=p;
            else ans=1-p;
            return ans;
        }
        if(k==fa[r-1]+1){
            for(int i=1;i<r;i++) ans*=p;
            ans*=(1-p);
        }
        else if(k<fa[r-1]+1){
            for(int i=1;i<r;i++) ans*=p;
            double now=cal(r-1,k);
            ans=ans*(now*p+(1-now)*(1-p));
        }
        else{
            while(k>fa[r-1]+1){
                k-=fa[r-1];
                r--;
                ans*=(1-p);
            } 
            ans*=solve(r,k);
        }
        return ans;
    }
    
    int main(){
        ios::sync_with_stdio(false);cin.tie(0);
        int T;cin>>T;
        fa[0]=1; 
        for(int i=1;i<=63;i++) fa[i]=fa[i-1]*2;
        while(T--){
            int r; ll k;
            cin>>r>>k>>p;
            double ans=solve(r,k);
            printf("%.6lf
    ",ans); 
        }
    }
    View Code

    F. The Chosen One

    签到java大数题,kele

    import java.math.BigInteger;
    import java.util.Scanner;
    
    public class Main{
        public static void main(String[] args){
            Scanner input = new Scanner(System.in);
            
            int t = input.nextInt();
    
            while (t > 0) {
                BigInteger m = input.nextBigInteger();
                BigInteger ans = (new BigInteger("2")).pow(m.bitLength() - 1);
                System.out.println(ans);
                t--;
            }
    
            input.close();
        }
    }
    View Code

    H.The Game of Life

    铜牌大模拟,我提供我(Anonytt)的写法,因为是个无限大的图,但是最多就321次衍生,所以实际上最终图的大小是不会超过(2*321+n)*(2*321+m),为了方便所以我就把初始点全部行列+400。然后记录当前是活着的点,把他们存在set里,然后并对活着的周边8个点的cnt进行统计。每次更新,用queue队列来缩减时间。

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,n) for(int i=a;i<=n;i++)
    #define per(i,n,a) for(int i=n;i>=a;i--)
    #define endl '
    '
    #define eps 0.000000001
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define IO ios::sync_with_stdio(false);cin.tie(0);
    using namespace std;
    const int INF=0x3f3f3f3f;
    const ll inf=0x3f3f3f3f3f3f3f3f;
    const int mod=1e9+7;
    const int maxn=1e5+5;
    int a[900][900],cnt[900][900];
    int dx[9]={1,-1,0,0,1,1,-1,-1};
    int dy[9]={0,0,1,-1,1,-1,1,-1};
    int n,m;
    int main(){
        int T;scanf("%d",&T);
        while(T--){
            mem(a,0);mem(cnt,0);
            scanf("%d%d",&n,&m);
            int maxx=0,id=0;
            set<pair<int,int> >s;
            rep(i,1,n){
                rep(j,1,m){
                    char xx;cin>>xx;
                    if(xx=='#'){
                        int u=i+400,v=j+400;
                        a[u][v]=1;++maxx;
                        rep(o,0,7){
                            int x=u+dx[o],y=v+dy[o];
                            cnt[x][y]+=1;
                            s.insert({x,y});
                        }
                        s.insert({u,v});
                    }
                    else a[i+400][j+400]=0;
                }
            }
            int c;
            rep(t,1,321){
                int cur=0;
                queue<pair<int,int> >q;
                for(auto it:s){
                    int x=it.first,y=it.second;
                    if(cnt[x][y]==3&&!a[x][y]) {a[x][y]=1;++cur;q.push({x,y});}
                    else if((cnt[x][y]==2&&a[x][y])||(cnt[x][y]==3&&a[x][y])) {a[x][y]=1;++cur;q.push({x,y});}
                    else if((cnt[x][y]<=1&&a[x][y])||(cnt[x][y]>=4&&a[x][y])) {a[x][y]=0;}
                    cnt[x][y]=0;
                }
                if(cur>maxx) {maxx=cur,id=t;}
                if(t==321) c=cur;
                s.clear();
                if(t<321){
                    while(!q.empty()){
                        auto now=q.front();q.pop();
                        int x=now.first,y=now.second;
                        s.insert({x,y});
                    }
                    queue<pair<int,int> >que;
                    for(auto it:s){
                        int xx=it.first,yy=it.second;
                        rep(o,0,7){
                            int x=xx+dx[o],y=yy+dy[o];
                            cnt[x][y]+=1;que.push({x,y});
                        }
                    }
                    while(!que.empty()){
                        auto now=que.front();que.pop();
                        int x=now.first,y=now.second;
                        s.insert({x,y});
                    }    
                }
            }
            cout<<id<<" "<<maxx<<" "<<c<<endl;
        }
    }
    View Code

    I.Rake It In

    铜牌无脑暴力dfs。Anonytt,时间复杂度大概=200*pow(9,6)≈1e8,刚好能擦过,所以就无脑暴力吧

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,n) for(int i=a;i<=n;i++)
    #define per(i,n,a) for(int i=n;i>=a;i--)
    #define endl '
    '
    #define eps 0.000000001
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define IO ios::sync_with_stdio(false);cin.tie(0);
    using namespace std;
    const int INF=0x3f3f3f3f;
    const ll inf=0x3f3f3f3f3f3f3f3f;
    const int mod=1e9+7;
    const int maxn=1e5+5;
    int a[5][5],k;
    int find(int x,int y){
        int res=0;
        res+=a[x][y]+a[x+1][y]+a[x][y+1]+a[x+1][y+1];
        return res;
    }
    void rot(int x,int y){
        int temp=a[x][y];
        a[x][y]=a[x][y+1];
        a[x][y+1]=a[x+1][y+1];
        a[x+1][y+1]=a[x+1][y];
        a[x+1][y]=temp;
    }
    void back(int x,int y){
        int temp=a[x][y];
        a[x][y]=a[x+1][y];
        a[x+1][y]=a[x+1][y+1];
        a[x+1][y+1]=a[x][y+1];
        a[x][y+1]=temp;
    }
    int dfs(int t){
        if(t==2*k){
            int ans=INF,x,y;
            rep(i,1,3){
                rep(j,1,3){
                    ans=min(ans,find(i,j));
                }
            }
            return ans;
        }
        else{
            if(t%2==1){
                int ans=0,x,y;
                rep(i,1,3){
                    rep(j,1,3){
                        rot(i,j);
                        ans=max(ans,find(i,j)+dfs(t+1));
                        back(i,j);
                    }
                }
                return ans;
            }
            if(t%2==0){
                int ans=INF,x,y;
                rep(i,1,3){
                    rep(j,1,3){
                        rot(i,j);
                        ans=min(ans,find(i,j)+dfs(t+1));
                        back(i,j);
                    }
                }
                return ans;            
            }
        } 
    }
    int main(){
        int T;scanf("%d",&T);
        while(T--){
            scanf("%d",&k);
            rep(i,1,4){
                rep(j,1,4){
                    scanf("%d",&a[i][j]);
                }
            }
            cout<<dfs(1)<<endl;
        }
    }
    View Code

    J. Rearrangement

    签到,Anonytt

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,n) for(int i=a;i<=n;i++)
    #define per(i,n,a) for(int i=n;i>=a;i--)
    #define endl '
    '
    #define eps 0.000000001
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define IO ios::sync_with_stdio(false);cin.tie(0);
    using namespace std;
    const int INF=0x3f3f3f3f;
    const ll inf=0x3f3f3f3f3f3f3f3f;
    const int mod=1e9+7;
    const int maxn=1e5+5;
    int a[2*maxn];
    int main(){
        int T;scanf("%d",&T);
        while(T--){
            int n;scanf("%d",&n);
            int cnt1=0,cnt2=0,cnt3=0;
            rep(i,1,2*n){
                scanf("%d",&a[i]);
                if(a[i]%3==0) cnt3++;
                if(a[i]%3==1) cnt1++;
                if(a[i]%3==2) cnt2++;
            }
            if(cnt3>n) {puts("NO");continue;}
            if(cnt3==n){puts("YES");continue;}
            else if(cnt3==0){
                if(cnt1&&cnt2) puts("NO");
                else puts("YES");
            }
            else if(cnt3==1){
                if(cnt1&&cnt2) puts("NO");
                else puts("YES");
            }
            else if(cnt3==2){
                if(cnt1%2==0&&cnt2%2==0){puts("NO");continue;}
                else puts("YES");
            }
            else puts("YES");
        }
    }
    View Code

     L. Twice Equation

    大数java+板子,kele

    import java.math.BigInteger;
    import java.util.Scanner;
    
    public class Main{
        public static void main(String[] args){
            Scanner input = new Scanner(System.in);
    
            int t = input.nextInt();
            BigInteger[] a = new BigInteger[1000];
    
            a[0] = BigInteger.ZERO;
            a[1] = BigInteger.valueOf(3);
    
            BigInteger ke = new BigInteger("6");
            BigInteger le = new BigInteger("2");
    
            for(int i = 2; i <= 400; i++){
                a[i] = ((a[i - 1].multiply(ke)).subtract(a[i - 2])).add(le);
    //             System.out.println(a[i]);
            }
            for(int i = 0; i < t; i++) {
                boolean flag = false;
                BigInteger L = input.nextBigInteger();
                for(int j = 0; j <= 400; j++){
                    if(a[j].compareTo(L) >= 0){
                        System.out.println(a[j]);
                        flag = true;
                        break;
                    }
                }
                if(!flag) System.out.println(-1);
            }
    
            input.close();
        }
    }
    View Code

    M.The Maximum Unreachable Node Set

    (赛后通过Anonytt),其实就是一个最大独立集的问题,不过需要之前用floyd转化,其实看出最大独立集不难,关键是想到floyd转化

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,n) for(int i=a;i<=n;i++)
    #define per(i,n,a) for(int i=n;i>=a;i--)
    #define endl '
    '
    #define eps 0.000000001
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define IO ios::sync_with_stdio(false);cin.tie(0);
    using namespace std;
    const int INF=0x3f3f3f3f;
    const ll inf=0x3f3f3f3f3f3f3f3f;
    const int mod=1e9+7;
    const int maxn=1e5+5;
    int n,m,line[505][505],used[505],match[505];
    int find(int x){
        rep(i,1,n){
            if(!used[i]&&line[x][i]){
                used[i]=true;
                if(match[i]==0||find(match[i])){
                    match[i]=x;
                    return true;
                }
            }
        }
        return false;
    }
    int main(){
        int T;scanf("%d",&T);
        while(T--){
            scanf("%d%d",&n,&m);
            mem(line,0);mem(match,0);
            rep(i,1,m){
                int u,v;scanf("%d%d",&u,&v);
                line[u][v]=1;
            }
            rep(k,1,n){
                rep(i,1,n){
                    rep(j,1,n){
                        if(line[i][k]&&line[k][j]) line[i][j]=1;
                    }
                }
            }
            int ans=0;
            rep(i,1,n){
                mem(used,0);
                if(find(i)) ++ans;
            }
            printf("%d
    ",n-ans);
        }
    }
    View Code

    再接再厉啊,希望现场icpc区域赛能有银牌qwq

  • 相关阅读:
    NS网络仿真,小白起步版,双节点之间的模拟仿真(基于UDP和CBR流)
    Linux学习,ACL权限管理
    SQL中的注释语句
    C#连接SQL Server数据库小贴士
    C#重写ToString
    C#控制台应用程序之选课系统
    浅谈C、C++及其区别、兼容与不兼容
    C++之客户消费积分管理系统
    A*算法
    HTML标签列表总览
  • 原文地址:https://www.cnblogs.com/Anonytt/p/13365940.html
Copyright © 2020-2023  润新知