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;
}