这是一个我关注的算法爷所举办的比赛,对于我来说,也有一定的经验丰收,通过做这些题可以加强自己的思维能力。
A:小朋友过马路
题目描述
有n个小朋友排成一排过马路,第i个小朋友身高为ai, 小e想知道有多少个小朋友比身边的两个小朋友都严格地高。
输入格式
第一行一个整数T(1≤T≤1000)表示样例个数。
对于每一个样例:
第一行两个整数n(1≤n≤105)。
第二行n个整数表示ai(1≤ai≤109)。
数据保证∑n≤2×105
输出格式
对于每组测试用例,输出一个整数表示结果。
输入样例
2
3
1 2 1
5
1 2 1 3 2
输出样例
1
2
解题思路:
这个题属于签到题,我们只需要按照题目说的意思去做就行了,严格高于意思就是不能是等于,必须是大于,这点需要注意。
#include <iostream>
#include <vector>
using namespace std;
int main() {
int T;
cin >> T;
while (T--) {
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; ++i) {
cin >> a[i];
}
int count = 0;
for (int i = 1; i < n - 1; ++i) {
if (a[i] > a[i - 1] && a[i] > a[i + 1]) {
count++;
}
}
cout << count << endl;
}
return 0;
}
B:平衡出题
题目描述
你是StarryCoding一场比赛的出题者,你准备了n个问题,其中第i个问题的难度为ai。你将进行以下流程:
· 从列表中删除一些问题(可能是零个)
· 将剩下的问题按任意顺序重新排序
当且仅当任意两个连续问题的难度之差的绝对值小于等于𝑘k时,这场比赛才算平衡。
为了使问题的排序达到平衡,你至少需要删除多少个问题?
输入格式
第一行包含一个整数 t(1≤t≤1000) 表示测试用例数量。
每个测试用例的第一行包含两个正整数 n(1≤n≤2×105) 和 k(1≤k≤109) 表示问题数和连续问题之间允许的最大绝对差值。
每个测试用例的第二行包括 n 个空格分隔的整数 ai(1≤ai≤109) 表示每个问题的难度
输出格式
对于每个测试用例,输出一个整数,表示为使问题平衡,你必须删除的最小问题数
输入样例
7
5 1
1 2 4 5 6
1 2
10
8 3
17 3 1 20 12 5 17 12
4 2
2 4 6 8
5 3
2 3 19 10 8
3 4
1 10 5
8 1
8 3 1 4 5 10 7 3
输出样例
2
0
5
0
3
1
4
解题思路:
这个题,我们可以这么想:先给这个数组排序,排好序之后,有单调性,然后我们求其最长的能够符合要求的子序列,再用数组元素总数减去子序列的长度,就可以得到答案,所以这个问题的指向就为:如何求出符合要求的最长子序列?
设置maxlength代表最长,currentlength为目前长度,从第二个元素开始循环,因为第一个元素是没有讨论的必要的,符合要求currentlength就加一,不符合,就开始判断,maxlength取值为它与currentlength中最长的那一个,currentlength归一,一切重来,最后得到最长,再相减即可。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int t;
cin >> t;
while (t--) {
int n, k;
cin >> n >> k;
vector<int> a(n);
for (int i = 0; i < n; ++i) {
cin >> a[i];
}
sort(a.begin(),a.end());
int max_length = 1;
int current_length = 1;
for (int i = 1; i < n; ++i) {
if (abs(a[i] - a[i - 1]) <= k) {
current_length++;
} else {
max_length = max(max_length, current_length);
current_length = 1;
}
}
max_length = max(max_length, current_length);
int min_deletions = n - max_length;
cout << min_deletions << endl;
}
return 0;
}
C:这是啥数?
题目描述
给定一个由 n 个元素组成的数组 𝑎 ,求数组在执行下列操作 任意次 后的最大和:
输入格式
输入由多个测试用例组成。第一行包含一个整数 T (1≤T≤1000) - 测试用例的数量。测试用例说明如下:
每个测试用例的第一行都包含一个整数 n (2≤n≤2⋅105) - 数组的长度。
下一行包含 n 个空格分隔的整数 a1,a2,…,an (−109≤ai≤109) 。
保证所有测试用例中 n 的总和不超过 2⋅105 。
输出格式
对于每个测试用例,输出数组在执行所述操作任意次数后可能具有的最大和。
输入样例
5
3
-1 -1 -1
5
1 5 -5 0 2
3
1 2 3
6
-1 10 9 8 7 6
2
-1 -1
输出样例
1
13
6
39
2
解题思路:
无论进行多少次操作,负数个数的奇偶性都不会改变。(基本规则)
如果负数的个数是偶数 ,最大值就是所有数字的绝对值之和,因为负数个数的奇偶性是不会改变的,那么我们通过若干次变换,总能得到负数个数为0的数组。
如果负数的个数是奇数 ,那么若干次变换后最后一定有一个负数。我们将选择绝对值最小的一个,其余的保持正数(为简单起见,我们将 0 视为负数)
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int T;
cin >> T;
while(T --)
{
int n;
cin>>n;
vector<int> a(n);
for(auto &x : a)
cin >> x;
int ans = 0, cnt = 0, mi = 9999;
for(auto &x : a)
{
if(x < 0)
{
cnt ++;
x = -x;
}
ans += x;
mi = min(mi, x);
}
cout << (cnt & 1 ? ans - 2 * mi : ans) <<endl;
}
return 0;
}
D:公平数
题目描述
如果一个正整数能被它的每个位上的非零数字整除,我们就称它为公平数。例如102是一个公平数(因为它可以被2和8整除),但282不是(因为它不能被8整除)。现在给定一个正整数n,求最小的一个正整数x满足以下条件:
- x≥n;
- x是一个公平数。
输入格式
第一行包含一个整数T(1≤T≤1000),表示测试用例组数。
接下来𝑇T行每行都包含一个正整数n(1≤n≤1018)。
输出格式
每个测试用例打印一个整数。
输入样例
4
1
282
1234567890
1000000000000000000
输出样例
1
288
1234568040
1000000000000000000
解题思路:
如果一个正整数能被它每一位上的非零数字整除,那么这个正整数也能被它的每一位上非零数字的LCM整除。而LCM(1...9)=2520,所以符合条件的解一定不超过n+2520。所以我们依次枚举比n大的每一个数并判断是否符合条件即可。
#include <bits/stdc++.h>
using namespace std;
#define int long long
int gcd(int a,int b){return b == 0 ? a : gcd(b,a % b);}
int lcm(int a,int b){return a * b / gcd(a,b);}
bool check(int n)
{
int x = n;
while(x)
{
int k = x % 10;
if(k != 0)
{
if(n % k != 0)return false;
}
x /= 10;
}
return true;
}
void solve()
{
int n;cin >> n;
while(!check(n))n++;
cout << n << '\n';
}
signed main()
{
int t;cin >> t;
while(t--)solve();
}
E:特别的多项式
题目描述
Piper近日又开始研究上了多项式,但是这次𝑃𝑖𝑝𝑒𝑟Piper研究的多项式并非普通的多项式了。
我们知道,一元𝑛n次多项式可以用如下的表达式来表示:
为了有趣一些,Piper规定:一个由不同非负整数组成的数组b,由这个数组b中所有元素得到一个多项式,其中bi次项的系数为1,将一个正数n代入这个多项式得到的计算结果是特殊数。
换句话说,如果一个正数可以写成 n 的不同非负幂的和,我们就称它为特殊数。例如,对于 n=4 来说,数字 17 是特殊的,因为它可以写成 40+42=1+16=17 ,但 9 不是。
但是Piper懒惰的毛病又犯了,可是他又想快速地找到按递增顺序排列的 k 这个特殊的数字。请你写个程序来帮助Piper。因为这个数可能太大,所以输出它的模数 109+7 。
输入描述
第一行包含一个整数 t ( 1≤t≤104 ) - 测试用例数。
每个测试用例的第一行,也是唯一一行,包含两个整数 𝑛n 和 k ( 2≤n≤109 ; 1≤k≤109 )。
输出描述
输入样例
输出样例
解题思路:
byd这题不会,有没有佬教教
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int p = 1e9 + 7;
void solve()
{
ll n, k; cin >> n >> k;
ll temp = 1;
ll ans = 0;
for(int i = 0; i < 31; ++i)
{
if(k & (1 << i))
{
ans = (ans + temp) % p;
}
temp *= n;
temp %= p;
}
cout << ans << '\n';
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int _; cin >> _;
while(_--) solve();
return 0;
}
当时AC了三道,第四题后来看懂了,第五题还是不会,等会了再来更新