ICPC 2021网络赛2The 2021 ICPC Asia Regionals Online Contest (II)签到题5题

Posted 小哈里

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ICPC 2021网络赛2The 2021 ICPC Asia Regionals Online Contest (II)签到题5题相关的知识,希望对你有一定的参考价值。

M. Addition

题意:

  • 给出n,接下来三行,每行n位二进制数,分别表示符号sgn{-1,1}和a{0,1}, b{0,1}。
  • 令c=a+b(a和sgn每位相乘得到数a),最后将c拆成每一位输出。

思路:

  • 暴力把va和vb算出来,得到vc,然后每一位拆出来判断进位即可。(考场的时候pows用了自带的然后卡精度改了好久)
//M
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e4+10;
LL pows( LL a, LL b){
    if(b==0)return 1;
    LL ns = pows(a,b>>1);
    ns = ns*ns;
    if(b&1)ns = ns*a;
    return ns;
}

int sgn[maxn], a[maxn], b[maxn], c[maxn];

int main(){
    int n;  cin>>n;
    for(int i = 0; i < n; i++)cin>>sgn[i];
    for(int i = 0; i < n; i++)cin>>a[i];
    for(int i = 0; i < n; i++)cin>>b[i];

    LL va = 0, vb = 0;
    for(int i = 0; i < n; i++) va += pows(2,i)*a[i]*sgn[i];
    for(int i = 0; i < n; i++) vb += pows(2,i)*b[i]*sgn[i];

    LL vc = va+vb;
    // vc=-7;
    // n = 4;
    // sgn[0]=-1; sgn[1] = -1; sgn[2] = 1; sgn[3] = 1;
    for(int i=0;i<n;i++){
        if(((vc>>i)&1)){
            if(sgn[i]==-1){
                c[i]=1;
                vc+=pows(2,i+1);
            }
            else{
                c[i]=1;
            }
        }
        else
            c[i]=0;
        // cout<<vc<<'\\n';
        if(i!=0)cout<<" ";
        cout<<c[i];
    }
    return 0;
}

J Leaking Roof

题意:

  • 给出一个n*n的矩阵表示屋顶每块瓦片的高度,现在初始每片上都有m的雨水。
  • 每片上的雨水都会均匀的流向比他低的瓦片上,求足够上时间后,所有高度0瓦片上的雨水量

思路:

  • 给所有瓦片按高度排个序,然后从高到低流即可。
//J
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 550;

int h[maxn][maxn];
double a[maxn][maxn];
struct node{int x, y, h; double v;};
vector<node>G;
bool cmp(node x, node y){return x.h>y.h;}

int dx[] = {-1,1,0,0};
int dy[] = {0,0,-1,1};

int main(){
    int n, m;  cin>>n>>m;
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++){
            cin>>h[i][j];
            a[i][j] = (double)m;
            G.push_back({i,j,h[i][j],(double)m});
        }
    }
    sort(G.begin(),G.end(),cmp);
    for(auto x : G){
        int cnt = 0;
        for(int i = 0; i < 4; i++){
            int nx = x.x+dx[i], ny = x.y+dy[i];
            if(nx>n||ny>n||nx<1||ny<1)continue;
            if(h[nx][ny]<x.h){
                cnt++;
            }
        }
        for(int i = 0; i < 4; i++){
            int nx = x.x+dx[i], ny = x.y+dy[i];
            if(nx>n||ny>n||nx<1||ny<1)continue;
            if(h[nx][ny]<x.h){
                a[nx][ny] += a[x.x][x.y]/cnt;
            }
        }
        if(cnt!=0)a[x.x][x.y] = 0;
    }
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++){
            if(j!=1)cout<<" ";
            if(h[i][j]!=0)cout<<"0";
            else printf("%.6lf", a[i][j]);
        }
        if(i!=n)cout<<"\\n";
    }
    return 0;
}

H. Set

题意:

  • 定义集合S{1,2…256},给出k和r,要求构造S的k个子集I[i],满足对于任意的I[1]<I[2]<…I[r]<I[n], I[1-r并集]>=128, 且max{I}<512/r。

思路:

  • 直接rand所有的子集(虽然不知道怎么证明)
#include<bits/stdc++.h>
using namespace std;
int rand(int l, int r){ return rand()%(r-l+1)+l; }
int main(){
    srand(time(0));
    int k, r;  cin>>k>>r;
    for(int i = 1; i <= k; i++){
        set<int>se;
        while((int)se.size()<(512+r-1)/r)se.insert(rand(1,256));
        for(int j = 1; j <= 256; j++){
            cout<<se.count(j);
        }
        cout<<"\\n";
    }
    return 0;
}

G Limit

题意:

  • 给出n, a[i], b[i], t,求sum{a[i] * ln( 1+ b[i]*x) }/ (x^t)的极限{x->0}。

思路:

  • 直接泰勒展开,然而考场的时候泰勒不会
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL c[20];
int main(){
    int n, t;  cin>>n>>t;
    for(int i = 1; i <= n; i++){
        int a, b;  cin>>a>>b;
        LL cur = a;
        for(int j = 1; j <= t; j++){
            cur *= b;
            if(j%2==1)c[j] += cur;
            else c[j] += -cur;
        }
    }
    if(t==0){cout<<"0\\n"; return 0;}
    for(int i = 1; i < t; i++){
        if(c[i]){ cout<<"infinity\\n"; return 0; }
    }
    if(c[t]==0)cout<<"0\\n";
    else{
        LL d = (LL)abs(__gcd(1ll*t, c[t]));
        LL up = c[t]/d, dn = t/d;
        if(dn==1)cout<<up<<"\\n";
        else cout<<up<<"/"<<dn<<"\\n";
    }
    return 0;
}

K. Meal

题意:

  • n个人,n道菜,第i个人对第j道菜好感为a[i][j]。
  • n个人按序号轮流点菜,第i个人点到第j道菜的概率为a[i][j]/{S中剩余全部},把j从S中删除。
  • 求第i个人点到第j道菜的概率。

思路:

  • 状压dp
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1<<20;
const LL mod = 998244353;
LL pows(LL a, LL x, LL p){if(x==0)return 1; LL t = pows(a, x>>1,p);if(x%2==0)return t*t%p;return t*t%p*a%p;}
LL inv(LL x, LL p){ return pows(x,p-2,p);}

int n, a[20][20], p[20][20];
int f[maxn], s[maxn];

int main(){
    int n;  cin>>n;
    for(int i = 0; i < n; i++)
        for(int j = 0; j < n; j++)
            cin>>a[i][j];
    for(int i = 0; i < (1<<n); i++){
        int c = __builtin_popcount(i);//有多少个位为1
        for(int j = 0; j < n; j++)
            if(!(i>>j&1))s[i] += a[c][j];
        s[i] = inv(s[i],mod);
    }
    f[0] = 1;
    for(int i = 1; i < (1<<n); i++){
        int c = __builtin_popcount(i)-1;
        for(int j = 0; j < n; j++){
            if(!(i>>j&1)) continue;
            (p[c][j] += 1ll*f[i^(1<<j)]*a[c][j]%mod*s[i^(1<<j)]%mod) %= mod;
            (f[i] += 1ll*f[i^(1<<j)]*a[c][j]%mod*s[i^(1<<j)]%mod) %= mod;
        }
    }
    for(int i = 0; i < n; i++){
        for(int j = 0; j < n; j++){
            cout<<p[i][j];
            if(j==n-1)cout<<"\\n";else cout<<" ";
        }
    }
    return 0;
}

以上是关于ICPC 2021网络赛2The 2021 ICPC Asia Regionals Online Contest (II)签到题5题的主要内容,如果未能解决你的问题,请参考以下文章

2021 ICPC 网络赛2

2021 icpc网络赛总结

2021下半年ICPC各类赛事时间日程

2021ICPC网络赛第二场The 2021 ICPC Asia Regionals Online Contest (II) L Euler Function

2021年ICPC网络赛A题分析及代码

2021 ICPC网络赛第一场 A set+优先队列