Atcoder Beginner Contest 169题解

A

Description

给定 a a b b ,输出 a × b a×b

Solution

直接模拟即可。

Code

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

int a,b;

signed main()
{
	cin>>a>>b;
	cout<<a*b<<endl;
	
	return 0;
}

B

Description

给定 n n 个数,请求出它们的乘积。特别的,如果该值大于 1 0 18 10^{18} 则输出 1 -1

Solution

显然,由题意可以写出这个式子:

if (tot*a[i]>1000000000000000000)  return cout<<-1<<endl,0;

注意,这里的 t o t a i tot*a_i 会溢出!既然乘法不行,就用除法呗~

if (tot>1000000000000000000/a[i])  return cout<<-1<<endl,0;

注意,这两个式子可以互相转换的,依据是不等式的基本性质。

还有一件重要的事情——在判断溢出前,看一下给定的那些数中是否有 0 0 ,如果有就直接输出 0 0 并结束程序。

Code

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

int n,tot=1,a[200005];

signed main()
{
	cin>>n;
	for (int i=1;i<=n;i++)  cin>>a[i];
	for (int i=1;i<=n;i++)
	{
		if (a[i]==0)  return cout<<0<<endl,0;
	}
	for (int i=1;i<=n;i++)
	{
		if (tot>inf/a[i])  return cout<<-1<<endl,0;
		tot*=a[i];
	}
	cout<<tot<<endl;
	
	return 0;
}

C

不会做……

D

Description

尽可能多地把 n n 拆分为多个不同的,且是某个质数的正整数次方数 的数的乘积,并输出最多的个数。

Solution

做法显然。先质因数分解,即 n = i = 1 k a i b i n=∏_{i=1}^k a_i^{b_i}

可以得到,对于每对 ( a i , b i ) (a_i,b_i) ,我们需要将 b i b_i 拆分为 1 + 2 + 3 + + x + y 1+2+3+……+x+y ,并且要拆分得尽可能地多;所以,假设最多可以拆分为 n o w now 个,那么答案就是 n o w \sum now

注意质因数分解的时间复杂度需要限制在 O ( n ) O(\sqrt n) 以内,如果不会可以看我的另外一篇博客——质因数分解详解。

Code

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

int n,ans=0;

signed main()
{
	cin>>n;
	if (n==1)  return cout<<0<<endl,0;
	
	for (int i=2;i*i<=n;i++)
	{
		if (n%i==0)
		{
			int pos=0;
			while (n%i==0)  n=n/i,pos++;
			
			int now=sqrt(pos*2);
			if (now*(now+1)>pos*2)  now--;
			
			ans+=now;
		}
	}
	if (n>1)  ans++;
	cout<<ans<<endl;
	
	return 0;
}

E

Description

给定 n n l i l_i r i r_i ,且数组 a a 满足 l i a i r i ( 1 i n ) l_i≤a_i≤r_i(1≤i≤n) 。现在,请求出数组 a a 有多少种不同的中位数

solution

显然,我们要分奇偶类讨论。

n n 为奇数。
容易发现,此时中位数仅仅与 a a 数组中最中间的那个数 x x 有关。于是,我们将 l l 数组与 r r 数组按升序排序,那么有 l m i d x r m i d ( m i d = ( n + 1 ) / 2 ) l_{mid}≤x≤r_{mid}(mid=(n+1)/2) 。所以,此时中位数有 r m i d l m i d + 1 r_{mid}-l_{mid}+1 种。

n n 为偶数。
容易发现,此时中位数与 a a 数组中最中间的那两个数 x , y x,y 有关;只要 x + y x+y 的值不同,那么中位数就不同(中位数为 x + y 2 \frac {x+y} 2 )。于是,我们将 l l 数组与 r r 数组按升序排序,那么有 l l m i d + r l m i d x + y l r m i d + r r m i d l_{lmid}+r_{lmid}≤x+y≤l_{rmid}+r_{rmid} ,其中 ( l m i d = n / 2 , r m i d = l m i d + 1 ) (lmid=n/2,rmid=lmid+1) 。所以,此时中位数有 l r m i d + r r m i d l l m i d r l m i d + 1 l_{rmid}+r_{rmid}-l_{lmid}-r_{lmid}+1 种。

时间复杂度: O ( n ) O(n)

显然不可能做到这么优秀。

排序时间复杂度: O ( n l o g 2 n ) O(nlog_2n)
总时间复杂度: O ( n l o g 2 n ) O(nlog_2n)

Code

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

int n,ans;
int a[200005],b[200005];

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

F

Description

给定集合 a a (暂且当 a a 中数可以重复),请问存在多少个不同的 a a 的子集使得子集中存在子集的和为 s s ?

由于答案可能过大,请将其对 998244353 998244353 取模。

Solution

显然,如果集合 a a 的某个大小为 k k 的子集 S S 满足要求,那么它对答案的贡献就是 2 n k 2^{n-k}

然后设计状态,其中 d p i dp_i 表示所有数和为 i i 的子集对答案的贡献之和

接着,考虑状态转移。如果某个和为 s u m 1 sum_1 的子集大小为 k k ,添加了一个数 a i a_i 后成为了一个和为 s u m 1 + a i sum_1+a_i 且大小为 k + 1 k+1 的子集,贡献也除以了2(贡献从 2 n k 2^{n-k} 变成了 2 n k 1 2^{n-k-1} )。

所以,状态转移就是: d p j + = d p [ j a i ] / 2 dp_j+=dp[j-a_i]/2

但是,状态转移涉及到除法与取模,所以除以2要用逆元

时间复杂度: O ( n 2 ) O(n^2)

Code

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

int n,s;
int a[3005],dp[3005];

int quick_power(int x,int y)
{
	int res=1;
	for (;y;y=y>>1,x=(x*x)%mod)
	{
		if (y&1)  res=(res*x)%mod;
	}
	return res;
}

signed main()
{
	cin>>n>>s;
	for (int i=1;i<=n;i++)  cin>>a[i];
	
	dp[0]=quick_power(2,n);
	for (int i=1;i<=n;i++)
	{
		for (int j=s;j>=a[i];j--)  dp[j]=(dp[j]+(dp[j-a[i]]*499122177)%mod)%mod;
	}
	cout<<dp[s]<<endl;
	
	return 0;
}

总结

排名没进前3500,太惨了,赛后诸葛亮……

①A题切掉;
②B题WA了10次才AC,罚时50分钟;甚至有几次提交了同样的WA代码;心态崩溃;
④D题切掉;
⑤E题看都没看,直接搞B题去了……比赛后看到E题才发现如此简单;
⑥F题快速幂板子打错,且忘记逆元,不知道在搞啥QWQ

最终死得非常惨,大家不要学我这个菜鸡啊~

我艹%&#&@*

猜你喜欢

转载自blog.csdn.net/Cherrt/article/details/106601856
今日推荐