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题的主要内容,如果未能解决你的问题,请参考以下文章
2021ICPC网络赛第二场The 2021 ICPC Asia Regionals Online Contest (II) L Euler Function