2021年ICPC第二场网络赛

G.Limit

分析:
这是一道实在的数学题,需要一定的高数思维和基础。
看到0<=t<=5就应该想到,分子应该可以等价替换成一个与x的指数有关的表达式。那应该是什么表达式呢?没错,就是泰勒公式展开式
ln(1+x)=x-x^ 2/2+x ^3/3-x ^4/4+x ^5/5+…+(-1) ^(n-1)/n+…
想到这,这道题就已经没有难度了,只需要带进去看一下表达式就会发现接下来就是一道普通遍历的题了。

AC代码如下:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int a[maxn],b[maxn],g[10];
int main(){
	memset(g,0,sizeof(g));
	int n,t;cin>>n>>t;
	for(int i=1;i<=n;i++) cin>>a[i]>>b[i];
	for(int i=1;i<=n;i++){
		g[1]+=a[i]*b[i];
		g[2]+=a[i]*b[i]*b[i]*(-1);
		g[3]+=a[i]*b[i]*b[i]*b[i];
		g[4]+=a[i]*b[i]*b[i]*b[i]*b[i]*(-1);
		g[5]+=a[i]*b[i]*b[i]*b[i]*b[i]*b[i];
	}
	if(t==0) cout<<0<<endl;
	else{
		for(int i=1;i<t;i++){
		if(g[i]!=0) {
			cout<<"infinity"<<endl;
			return 0;
		}
	}
    cout<<g[t]/t<<endl;
	}
	
	return 0;
} 

H.Set

分析:
由于最大的一个区间<=(512/r),那么我们可以使每一个区间的所包含的元素个数为maxx=512/r。把256个元素均分为k份,由于此时可能出现余数(也就是有些元素没有得到均分),所以需要对余数p单独处理,将他们平均分配给任意一个可能分到的区间,(分到的区间加一,其他不变)。最后就是用star充当起点去遍历他们。每次起点记得加每一份的所属那部分区间d=256/k。

AC代码如下:

#include<bits/stdc++.h>
using namespace std;
int main(){
	int k,r,d,maxx,p;
	cin>>k>>r;
    d=256/k; maxx=512/r,p=256%k;
	int star=1;
	for(int i=1;i<=k;i++){
		int cnt=maxx; 
		for(int j=1;j<=256;j++){
		    if((j>=star||256-star+j<=maxx)&&cnt){
		    	cout<<1;
		    	cnt--;
			}
			else cout<<0;
		}
		star+=d;
		cout<<endl;
		if(p) star++,p--;
	}
	return 0;
}

J.Leaking Roof

分析:
一道类似于广度优先搜索的题,我们只需要将所有的点按照高度从大到小排序,然后从大到小遍历一次,将他们的水流分散给周围所有高度比它小的区域即可。最后输出高度为0的区域的水量,高度不为0的输出0即可。

AC代码如下:

#include<bits/stdc++.h>
using namespace std;
int n,k,cnt=0,h[505][505];
int dx[6]={0,-1,1,0,0};
int dy[6]={0,0,0,-1,1};
double ans[505][505];
struct Node{
	int x,y;
	int h;
	double m;
	bool operator < (const Node &a){
		return h>a.h;
	}
}g[505*505];
inline int check(int x,int y){
	if(x>=1&&x<=n&&y>=1&&y<=n) return 1;
	return 0;
}
void bfs(int k){
	int tot=0;
    for(int i=1;i<=4;i++){
    	int tx=g[k].x+dx[i];
    	int ty=g[k].y+dy[i];
    	if(check(tx,ty)&&h[tx][ty]<g[k].h) tot++;
	}
	 for(int i=1;i<=4;i++){
    	int tx=g[k].x+dx[i];
    	int ty=g[k].y+dy[i];
    	if(check(tx,ty)&&h[tx][ty]<g[k].h){
    		ans[tx][ty]+=ans[g[k].x][g[k].y]/tot;
		}
    }
}
void solve(){
	for(int i=1;i<=n;i++)
	    for(int j=1;j<=n;j++){
	    	cin>>h[i][j];
	    	g[++cnt].x=i;g[cnt].y=j;
	    	g[cnt].m+=k;
	    	ans[i][j]+=k;g[cnt].h=h[i][j];
		}
	sort(g+1,g+1+cnt);
	for(int i=1;i<=cnt;i++){
		bfs(i);
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(h[i][j]!=0) cout<<0<<" ";
			else printf("%.6lf ",ans[i][j]);
		}
		cout<<endl;
	}
}
int main(){
	cin>>n>>k;
	solve();
	return 0;
}

L.Euler Function

M.Addition

分析:
本题的难点在于进位的处理。一道签到题,却卡了好久,太菜了,qaq。
二进制数据从小到大相加时,由于进位多变化,可正可负数,还可为0;那么就需要统一处理了。将进位数jin乘上sgn[i],是为了让va[i]+vb[i]+jin的时候可以做到同号相加,异号相减。接下来就是分类讨论的过程,需要读者仔细思索了。

AC代码如下:

 #include<bits/stdc++.h>
using namespace std;
int main(){
	int n,sgn[100],va[100],vc[100],vb[100];cin>>n;
	for(int i=0;i<n;i++) cin>>sgn[i];
	for(int i=0;i<n;i++) cin>>va[i];
	for(int i=0;i<n;i++) cin>>vb[i];
	int jin=0;
	for(int i=0;i<n;i++){
		jin*=sgn[i];
		int temp=va[i]+vb[i]+jin;
		if(temp==0||temp==1) vc[i]=temp,jin=0;
		else if(temp==-1) vc[i]=1,jin=-1;
		else if(temp==2) vc[i]=0,jin=1;
		else if(temp==3)  vc[i]=1,jin=1;
        jin*=sgn[i];
	}
	for(int i=0;i<n-1;i++) cout<<vc[i]<<" ";
	cout<<vc[n-1];
	return 0;
}
/*
32
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

&が&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值