牛客小白月赛73

A

最小的数字

题意:

给定一个数n,求一个大于等于n且能被三整除的数。

题解:

从n开始往后找能被3整除的数即可。

代码:

#include<iostream>
#include<vector>
#include<map>
#include<math.h>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 2*1e5 + 10, inf = 1e9;
int n;
int x;
int main()
{
	cin >> n;
	for (int i = n;; i++)
		if (i % 3 == 0)
		{
			cout << i;
			return 0;
		}
}

B

优美的GCD

题意:

 给出一个整数n,n为x,y的最大公约数,求符合条件的x,y值。

题解:

首先n本身肯定满足条件,2*n也满足,所以对于所有的n,我们都可以有x=n,y=2*n。

代码:

#include<iostream>
#include<vector>
#include<map>
#include<math.h>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 2*1e5 + 10, inf = 1e9;
int n, t;
int x, y;
int main()
{
	cin >> t;
	while (t--)
	{
		cin >> n;
		cout << n <<' '<< n + n << endl;
	}
	return 0;
}

C

优美的序列

题意:

给定一个长度为n的序列,判断其通过交换数据位置来使其为优美序列。

优美序列:

 

题解:

我们可以通过交换数据位置使序列变为单调递增的,这时我们发现,只要没有相同的数字,序列就为优美序列。(相同数字相邻,它们的差为0,不满足条件)

代码:

#include<iostream>
#include<vector>
#include<map>
#include<math.h>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 2*1e5 + 10, inf = 1e9;
int n, t;
int a[1100];
int main()
{
	cin >> t;
	while (t--)
	{
		map<int, int>m;
		int flag = 0;
		cin >> n;
		for (int i = 1; i <= n; i++)
		{
			cin >> a[i];
			m[a[i]]++;
		}
		for (const auto& i : m)
		{
			if (i.second > 1)
			{
				flag = 1;
				break;
			}
		}
		if (flag == 1)
			cout << -1;
		else
		{
			sort(a + 1, a + n + 1);
			for (int i = 1; i <= n; i++)
				cout << a[i] << ' ';
		}
		cout << endl;
	}
	return 0;
}

D

Kevin喜欢零(简单版本)

题意:

给你一个长度为n的序列,求其子序列各数之积中有多少个后导零为k。

题解:

本题数据较大,暴力做法会导致超时,显然不可行。

我们可以先通过前缀积预处理序列,因后导零只会越乘越多,所以前缀积数列中的后导零个数是递增的。

满足这个条件后,我们就可以用二分求出后导零为k个的子序列个数了。

可以写一个cheak函数用来判断后导零的个数,然后用二分求出后导零个数为k在前缀积序列中的左右端点即可。

代码:

#include<iostream>
#include<vector>
#include<map>
#include<math.h>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 2*1e5 + 10, inf = 1e9;
ll n, k;
ll a[N];
ll s[N];
void init()
{
	s[0] = 1;
	for (int i = 1; i <= n; i++)
		s[i] = s[i - 1] * a[i];
}
int check(ll q)
{
	ll res = 0;
	while (q && q % 10 == 0)
	{
		res += 1;
		q /= 10;
	}
	return res;
}
void solve()
{
	cin >> n >> k;
	for (int i = 1; i <= n; i++)
		cin >> a[i];
	init();
	ll ans = 0;
	for (int i = 1; i <= n; i++)
	{
		int l = i, r = n;
		while (l < r)
		{
			int mid = l + r >> 1;
			if (check(s[mid] / s[i - 1]) >= k)
				r = mid;
			else
				l = mid + 1;
		}
		int left = l;
		l = i, r = n;
		while (l < r)
		{
			int mid = l + r + 1 >> 1;
			if (check(s[mid] / s[i - 1]) <= k)
				l = mid;
			else
				r = mid - 1;
		}
		int right = l;
		if (check(s[left] / s[i - 1]) == k)
			ans += right - left + 1;
	}
	cout << ans << endl;
}
int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		solve();
	}
	return 0;
}

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值