Atcoder Nomura 2020A-C题解

A

Solution

找出该段时间的分钟数 x x x k x-k 即为最终的答案。

Code

#include <bits/stdc++.h>
#define int long long
using namespace std;

int a,b,c,d,m;

signed main()
{
	cin>>a>>b>>c>>d>>m;
	cout<<(c*60+d)-(a*60+b)-m<<endl;
	
	return 0;
}

B

Solution

首先,思考一下 p d pd 的意义。它为总的答案贡献了2(一个 d d 和一个 p d pd ),而 d d dd 也为答案贡献了 2 2 (两个 d d )。

同时, d d 自己也能为答案产生 1 1 的贡献,而 p p 自己无法对答案产生任何贡献。

所以我们填 p p 干嘛呢?全填 d d 不就行了?
于是,我们在所有的’?'上填 d d ,再输出即为最终的答案。

Code

#include <bits/stdc++.h>
#define int long long
using namespace std;

int n;

signed main()
{
	string s;
	cin>>s;
	n=s.size();
	for (int i=0;i<n;i++)
	{
		if (s[i]=='?')  s[i]='D';
	}
	cout<<s<<endl;
	
	return 0;
}

花絮: 看完题面直接往 d p dp 方面想(只有 p p d d 啊)

C

Solution

首先,设 b i b_i 表示深度为 i i 的那一层中节点的数量

容易得到, b 1 = 1 , b n = a n b_1=1,b_n=a_n 。注意最后一层的所有节点均为叶节点

于是,我们从两个角度开始推。

①已知 b 1 = 1 b_1=1
容易发现,第 i i 层非叶节点的数量就是 b i a i b_i-a_i ;由于这是一棵可爱的二叉树,并且要让答案最大;所以我们要让这 b i a i b_i-a_i 个非叶节点的孩子的数量都是2

我知道您觉得单独考虑这东西不行,因为 b n b_n 不一定是 a n a_n ——于是我们考虑第二种情况。

②已知 b n = A n b_n=A_n
首先,每个节点有且仅有一个父节点。所以,第 i i 层的节点的数量就是第 i + 1 ( i n ) i+1(i<n) 的节点的数量**加上第 i i 层的叶节点的数量。直接递推。

我知道您很奇怪—— b 1 b_1 不一定是1啊~于是,我们决定结合①②考虑答案


现在,我们通过这两种情况,大概得出了 b i b_i 的值。

容易发现,一层的节点的个数多了是不好的(这是一棵二叉树,如果每一层的节点数量都少那么这种树一定存在);所以, b i b_i 通过上述两种情况计算出答案分别为 x , y x,y 时, b i = m i n ( x , y ) b_i=min(x,y)

注意,当 a i > x i a_i>x_i 时(不可能在这一层产生这么多的叶节点),应该直接输出 1 -1

于是答案就是 Σ i = 1 n b i Σ_{i=1}^n b_i 。时间复杂度 O ( n ) O(n)


什么?要用高精度?

本蒟蒻解释一下为什么不用高精度。首先,对于任何一棵树,从上到下,每一层节点的数量一定是单调不减的。第 n n 层的节点的数量 ( b n ) (b_n) 一定是每层节点个数中的最大值,所以答案一定小于 b n × n b_n×n ,即 1 0 13 10^{13} 。既然最大值就这么一点,那么我们用 l o n g long l o n g long 存储就可以了。

既然不用高精度,代码就简短啦~

Code

#include <bits/stdc++.h>
#define int unsigned long long
using namespace std;

int n,ans=0;
int a[100005],b[100005],c[100005];

int p[100005][205];

signed main()
{
	cin>>n;
	n++;
	for (int i=1;i<=n;i++)  cin>>a[i];
	
	b[1]=1,c[n]=a[n];
	for (int i=2;i<=n;i++)  b[i]=(b[i-1]-a[i-1])*2;
	for (int i=n-1;i>=1;i--)  c[i]=c[i+1]+a[i];
	for (int i=1;i<=n;i++)  ans+=min(b[i],c[i]);
	for (int i=1;i<=n;i++)
	{
		if (a[i]>b[i])  return cout<<-1<<endl,0;
	}
	cout<<ans<<endl;
	
	return 0;
}

撒花✿✿ヽ(°▽°)ノ✿撒花

猜你喜欢

转载自blog.csdn.net/Cherrt/article/details/106447739