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 '\n'
#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 '\n'
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\n",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 '\n'
#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 '\n'
#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 '\n'
#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 '\n'
#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",n-ans);
    }
}
View Code

 

 

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

posted @ 2020-07-23 13:57  Anonytt  阅读(334)  评论(0编辑  收藏  举报