ICPC网络赛第二场 2021.9.25

第二场题目更加偏向数学,可惜学算法的时候把高数丢了,第二场罚坐五小时。

比完赛后面去看了三道被称为签到题的题解。下面是这三道题的思路和代码。

Problem G. Limit

Given 2n integers,a1,a2,...,an,b1,b2,...,bn,and an integer t. You need to calculate:

这道题就是计算该公式,搜了下题解基本都是用的泰勒展开,展开公式如下:

\frac{\sum a_{i}(b_{i} - \tfrac{b_{i}^{2}}{2}{x^{2}} + \tfrac{b_{i}^{3}}{3}{x^{3}} - \tfrac{b_{i}^{4}}{4}{x^{4}} + \tfrac{b_{i}^{5}}{5}{x^{5}})}{x^{t}}

代码如下:

#include<iostream>
using namespace std;

const int N = 100005;
int a[N],b[N],g[5];
int main()
{
	int n,t;
	cin>>n>>t;
	if(t == 0)
	{
		cout<<0;
		return 0;
	}
	for(int i = 1; i <= n; i++)
	{
		cin>>a[i]>>b[i];
		g[0] += a[i] * b[i];
		g[1] -= a[i] * b[i] * b[i];
		g[2] += a[i] * b[i] * b[i] * b[i];
		g[3] -= a[i] * b[i] * b[i] * b[i] * b[i];
		g[4] += a[i] * b[i] * b[i] * b[i] * b[i] * b[i];
	}
	for(int i = 0; i < t - 1; i++)
	{
		if(g[i])
		{
			cout<<"infinity";
			return 0;
		}
	}
	cout<<g[t - 1] / t;
	return 0;
}

Problem J. Leaking Roof

        该题大概题意就是有n * n块屋顶,现在有场强降雨,降水量为每块屋顶m的水,且水流会从高处流向低处,若未流动的屋顶块记为0。问最后这n * n块屋顶每块的含水量。

解题思路:从屋顶最高的点向低处遍历,每次判断该屋顶的上下左右四块相邻屋顶能否流水,能流就均等流向相邻低的屋顶。最后输出每个点的最终含水量。

代码如下:

#include<iostream>
#include<algorithm>
#include<iomanip>
#define int long long
using namespace std;

int h[505][505],cnt = 0,n,m;
double s[505][505];
int dx[4] = {1,0,-1,0};
int dy[4] = {0,1,0,-1};

//结构体存放每个点的坐标和屋顶高度 
struct node{
	int x,y,h;
	//结构体按照屋顶高度逆序排序 
	bool operator < (const node p){
		return h > p.h;
	}
}a[300005];

//处理t点的水流 
void judge(node t)
{
	int sum = 0;
	//遍历该点的四个方向能否流水 
	for(int i = 0; i < 4; i++)
	{
		int X = t.x + dx[i];
		int Y = t.y + dy[i];
		//水流能够流向(X,Y) 
		if(X >= 0 && X < n && Y >= 0 && Y < n && h[t.x][t.y] > h[X][Y])
		{
			sum++;
		}
	}
	//若该点水流有可流方向 
	if(sum)
	{
		//遍历四个方向找出可以流向的点 
		for(int i = 0; i < 4; i++)
		{
			int X = t.x + dx[i];
			int Y = t.y + dy[i];
			//若水流能够流向(X,Y),为(X,Y)增添相应的水 
			if(X >= 0 && X < n && Y >= 0 && Y < n && h[t.x][t.y] > h[X][Y])
			{
				s[X][Y] += s[t.x][t.y] / sum;
			}
		}
	}
}
main()
{
	cin>>n>>m;
	for(int i = 0; i < n; i++)
	{
		for(int j = 0; j < n; j++)
		{
			cin>>h[i][j];
			//存入每个点的坐标和高度 
			a[cnt].x = i;
			a[cnt].y = j;
			a[cnt++].h = h[i][j];
			//为每个点赋初值 
			s[i][j] = m;
		}
	}
	int max0 = n * n;
	//房顶按高到低排序 
	sort(a,a + max0);
	//遍历每个点处理每个点的水流 
	for(int i = 0; i < max0; i++)
	{
		judge(a[i]);
	}
	for(int i = 0; i < n; i++)
	{
		for(int j = 0; j < n; j++)
		{
			//该点未漏水,记为0 
			if(h[i][j] != 0) cout<<0<<" ";
			else cout<<fixed<<setprecision(6)<<s[i][j]<<" ";
		}
		puts("");
	}
	return 0;
}

Problem M. Addition

        该题就是一个二进制运算的升级,除了二进制加法还增添了一个sgn_{i}来控制加减法。

解题思路:先对每位进行a_{i} + b_{i},然后判断每一位的数字是否合法,若不合法就判断sgn_{i}sgn_{i+1}的符号是否相同,相同就计算二进制加法,不同就计算二进制减法。

代码如下:

#include<iostream>
using namespace std;

int main()
{
	int n,a[65],b[65],c[65],ans[65];
	cin>>n;
	for(int i = 0; i < n; i++) cin>>c[i];
	for(int i = 0; i < n; i++) cin>>a[i];
	for(int i = 0; i < n; i++) cin>>b[i];
	for(int i = 0; i < n; i++) ans[i] = a[i] + b[i];
	for(int i = 0; i < n; i++)
	{
		if(ans[i] >= 2)
		{
			ans[i] -= 2;
			int j = i + 1;
			if(c[i] == c[j]) ans[j]++;
			else
			{
				if(ans[j] > 0) ans[j]--;
				else
				{
					while(c[i] != c[j])
					{
						if(ans[j] == 0)
						{
							ans[j] = 1;
							j++;
						}
						else
						{
							ans[j]--;
							break;
						}
					}
					if(c[i] == c[j]) ans[j]++;
				}
			}
		}
	}
	cout<<ans[0];
	for(int i = 1; i < n; i++) cout<<" "<<ans[i];
	return 0;
}

代码源自网络,侵删

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值