本场A太弱智,BE考察思维,但是都比较容易想到,这里就不写这三题的题解了,主要写一下CDF三题的做法和思路。
本场比赛链接放在这里——第 17 场蓝桥算法赛
目录
C题题面
思路分析
按题意,我们寻找最多能挑选出的单独来自不同城池的猛将数量,首先我们可以开一个map记录一下不同城池里猛将的数量,map的长度表示城池的数量。但是要从小到大排序,map先转换为数组cnt[],方便排序和遍历。如果k小于等于mp.size()则直接输出k即可,因为此时一人一个城池情况下,数量刚刚好或者用不完。否则,我们可根据贪心思想,每次把(k - mp.size())放进容纳人数最多的城池里,这样就能得到题意中“所叙述的最多城池数量”,当剩余数小于等于0时,我们把答案输出。
代码实现
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <climits>
#define int long long
#define x first
#define y second
using namespace std ;
typedef pair<int,int> PII;
const int N = 1e5 + 10;
int a[N];
vector<int> cnt;
PII p[N];
map<int,int> mp;
void solve()
{
int n,k;
cin >> n >> k;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i <= n; i++) mp[a[i]] ++;
for(auto &c : mp) cnt.push_back(c.y);
sort(cnt.begin() , cnt.end() , greater<int>());//从大到小排序
int ans = 0;
if(k <= mp.size())
{
cout << k << endl;
return;
}
else
{
int v = k - mp.size();//k多出城池数量的部分
for(int i = 0; i < mp.size(); i++)
{
v = v + 1 - cnt[i];
if(v <= 0)
{
cout << mp.size() - i - 1 << endl;
return;
}
}
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
int t = 1 ;
// cin >> t;
while(t -- ) solve();
return 0;
}
D题题面
思路分析
这个题意其实非常容易理解,也是个思维题,找对规律即可,如果x >= y * k,则直接减掉输出即可,如果x < y*k且 y > x 时,做奇数次询问结果为abs(x - y),偶数次询问结果就为x,但如果x < y*k且 y < x 时我们先把操作进行到 y > x然后再按规律正常输出——
代码实现
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <climits>
#define int long long
#define x first
#define y second
#define ct cout
using namespace std ;
typedef pair<int,int> PII;
const int N = 1e5 + 10;
int a[N];
PII p[N];
void solve()
{
int x,y,k;
cin >> x >> y >> k;
int ans = y * k;
if(x >= ans) ct << x - ans << endl;
else
{
int c = x / y;
k -= c;
x %= y;
if(k % 2) ct << abs(x - y) << endl;
else ct << x << endl;
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
int t ;
cin >> t;
while(t -- ) solve();
return 0;
}
F题题面
思路分析
质因数分解 + 快速幂
代码实现
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <climits>
#define int long long
#define x first
#define y second
using namespace std ;
typedef pair<int,int> PII;
const int N = 1e5 + 10;
const int mod = 998244353;
int a[N];
PII p[N];
int qmi(int a,int b,int p) //快速幂(求 a ^ b % p)
{
int res = 1 % p;
while(b)
{
if(b & 1) res = res * a % p;
a = a * a % p;
b >>= 1;
}
return res;
}
void solve()
{
int n, m;
cin >> n >> m;
vector<int> arr;
int x = m;
for(int i = 2; i <= x /i; i++)
{
if(x % i == 0)
{
int s = 0;
while(x % i == 0) x /= i,s++;
arr.push_back(s);
}
}
if(x > 1) arr.push_back(1);
int res = 1;
for(auto &c : arr)
{
int cnt = (qmi(c + 1,n,mod) - qmi(c,n,mod) + mod) % mod;// 16 - 9 = 7
res = (res * cnt % mod) % mod;
}
cout << res << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
int t = 1;
//cin >> t;
while(t -- ) solve();
return 0;
}
写到这实在太困了,没有休息好,睡觉去了www,明天补前几天打的牛客两场的题解——