2024牛客寒假算法基础集训营5 题解 ( A,C,G,H,I,L,M )
2024牛客寒假算法基础集训营5 题解 ( A,C,G,H,I,L,M )
A mutsumi的质数合数
题意
有一个由
思路
由质数和合数的定义可知,正整数范围内除
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;
cin >> n;
int cnt = 0;
for(int i = 0;i < n;i++){
int a;
cin >> a;
if(a != 0 && a != 1)cnt++;
}
cout << cnt;
return 0;
}
C anon的私货
题意
在一个正数数组中夹带一些 0,只要数组的除全 0 连续子数组外的每个连续子数组的平均数都大于等于 1,最多可以夹带多少个 0
思路
如果在两数之间插入
所以数组的第一个元素和最后一个元素要重点考虑,在数组前插
除此之外,设数组第
特别注意第一位和最后一位是否有剩余
代码
/*******************************
| Author: AlwaysBeShine
| Problem: anon的私货
| Contest: NowCoder
| URL: https://ac.nowcoder.com/acm/contest/67745/C
| When: 2024-02-21 15:48:37
|
| Memory: 524288 MB
| Time: 2000 ms
*******************************/
#include <bits/stdc++.h>
#include <limits.h>
using namespace std;
typedef long long ll;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;
cin >> n;
std::vector<ll> a(n+3,LLONG_MAX);
for(int i = 1; i <= n;i++){
cin >> a[i];
}
ll cnt = 0;
for(int i = 0;i <= n;i++){
if(a[i] >= 2 && a[i+1] >= 2){
if(a[i] >= a[i+1]){
cnt += a[i+1] - 1;
a[i] -= (a[i+1] - 1);
a[i+1] = 1;
}else{
cnt += a[i] - 1;
a[i+1] -= (a[i] - 1);
a[i] = 1;
}
}
// for(int i = 1; i <= n;i++){
// cout << a[i] << " \n"[i==n];
// }
}
if(a[1] >= 2)cnt += a[1] - 1;
cout << cnt;
return 0;
}
G sakiko的排列构造(easy)
题意
构造一个长度为
思路
通过打表可发现规律
设第
倒着构造,提前预处理出小于等于
因为要构造一个排列,所以数字不能重复,也不能大于
所以要求
否则
如果构造过程中
代码
/*******************************
| Author: AlwaysBeShine
| Problem: sakiko的排列构造(easy)
| Contest: NowCoder
| URL: https://ac.nowcoder.com/acm/contest/67745/G
| When: 2024-02-21 16:49:29
|
| Memory: 524288 MB
| Time: 2000 ms
*******************************/
/*******************************
| Author: AlwaysBeShine
| Problem: B3716 分解质因子 3
| Contest: Luogu
| URL: https://www.luogu.com.cn/problem/B3716
| When: 2024-02-11 15:50:18
|
| Memory: 600 MB
| Time: 2500 ms
*******************************/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<bool> isNotPrime(10100);
vector<int> prime;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
prime.push_back(2);
for(int i = 2;i <= 10000;i++){
if(isNotPrime[i] == false){
prime.push_back(i);
}
for(int j = 1;prime[j] * i <= 10000;j++){
int temp = prime[j] * i;
isNotPrime[temp] = true;
if(i % prime[j] == 0)break;
}
}
int pos;
int n;
cin >> n;
for(int i = 1;i <= prime.size();i++){
if(prime[i] > n){
pos = i;
break;
}
}
vector<int>ans(n+5);
map<int,int>mp;
for(int i = n;i >= 1;i--){ //倒着来
if(pos < 1){
cout << "-1";
return 0;
}
while(pos >= 1 && (prime[pos] - i > n || mp[prime[pos] - i] == 1)){
pos--;
}
if(mp[prime[pos] - i] == 0){ //如果没出现过这个数
if(prime[pos] - i <= n){ //必须要小于等于 n
ans[i] = prime[pos] - i;
mp[prime[pos] - i] = 1;
}else{ //如果大于等于n了或者出现过了
while(pos >= 1 && (prime[pos] - i > n || mp[prime[pos] - i] == 1)){
pos--;
}
if(pos < 1){
cout << -1;
}else{
ans[i] = prime[pos] - i;
mp[prime[pos] - i] = 1;
}
}
}
}
for(int i = 1;i <= n;i++){
cout << ans[i] << " ";
}
return 0;
}
H sakiko的排列构造(hard)
题意
同 easy 版,只有数据范围扩大到了
思路
同 easy 版
代码
/*******************************
| Author: AlwaysBeShine
| Problem: sakiko的排列构造(easy)
| Contest: NowCoder
| URL: https://ac.nowcoder.com/acm/contest/67745/G
| When: 2024-02-21 16:49:29
|
| Memory: 524288 MB
| Time: 2000 ms
*******************************/
/*******************************
| Author: AlwaysBeShine
| Problem: B3716 分解质因子 3
| Contest: Luogu
| URL: https://www.luogu.com.cn/problem/B3716
| When: 2024-02-11 15:50:18
|
| Memory: 600 MB
| Time: 2500 ms
*******************************/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<bool> isNotPrime(1000010);
vector<int> prime;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
prime.push_back(2);
for(int i = 2;i <= 1000010;i++){
if(isNotPrime[i] == false){
prime.push_back(i);
}
for(int j = 1;prime[j] * i <= 1000010;j++){
int temp = prime[j] * i;
isNotPrime[temp] = true;
if(i % prime[j] == 0)break;
}
}
int pos;
int n;
cin >> n;
for(int i = 1;i <= prime.size();i++){
if(prime[i] > n){
pos = i;
break;
}
}
vector<int>ans(n+5);
map<int,int>mp;
for(int i = n;i >= 1;i--){ //倒着来
if(pos < 1){
cout << "-1";
return 0;
}
while(pos >= 1 && (prime[pos] - i > n || mp[prime[pos] - i] == 1)){
pos--;
}
if(mp[prime[pos] - i] == 0){ //如果没出现过这个数
if(prime[pos] - i <= n){ //必须要小于等于 n
ans[i] = prime[pos] - i;
mp[prime[pos] - i] = 1;
}else{ //如果大于等于n了或者出现过了
while(pos >= 1 && (prime[pos] - i > n || mp[prime[pos] - i] == 1)){
pos--;
}
if(pos < 1){
cout << -1;
}else{
ans[i] = prime[pos] - i;
mp[prime[pos] - i] = 1;
}
}
}
}
for(int i = 1;i <= n;i++){
cout << ans[i] << " ";
}
return 0;
}
I rikki的最短路
题意
rikki 在找 anon ,她准备去找 tomorin 问一下 anon 在哪。 (以下tomorin简称
寻找过程:找到
我们把寻找过程简化为一条数轴, rikki 在数轴上的坐标为 0 ,
初始时 rikki 只知道
而当 rikki 到达
rikki 的视野为
rikki 想知道她将
思路
分类讨论
- 当
和 同向时,如果 ,那么在找 的过程中就找到了 直接带走,不需要多走,答案就是 - 当 A 和
同向时,如果 ,那就得比上面那种情况,多走 - 当
和 反向时,如果 ,一开始就知道 在哪,所以可以先找 ,再带到 处 - 当
时,同上理。 - 当
和 反向时,如果 ,得先去找 再去找 ,再找 。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
ll t,a,k;
cin >> t >> a >> k;
if((t > 0 && a > 0) || (t < 0 && a < 0)){ //同向
ll la = abs(a),lt = abs(t);
if(la <= lt){ //去t路上能看见a
cout << lt;
}else{ //看不见a
cout << la + la - lt;
}
}else if(a == 0){ //带着a去找t
cout << abs(t);
}else if(t == 0){ //直接知道a在哪 把他带回来
cout << 2 * abs(a);
}else{ //反向
if(abs(a) > k){
cout << 3*abs(t) + 2*abs(a);
}else{
cout << 2*abs(a) + abs(t);
}
}
return 0;
}
L anon的星星
题意
玩一个游戏,胜利一局会获得一颗星星,失败一局会失去一颗星星,没有平局。 只知道自己玩了
求胜利了几局,失败了几局?
思路
设胜利了
代码
#include <iostream>
using namespace std;
int main() {
int n, x;
cin >> n >> x;
for (int i = 0; i <= n; ++i) {
int j = n - i;
if (i - j == x) {
cout << i << " " << j << endl;
return 0;
}
}
cout << -1 << endl;
return 0;
}
M mutsumi的排列连通
题意
有两个排列,放置在一个
删除尽可能少的数字,使得矩形至少被分成两个连通块(不一定是矩形),
请输出最小的删除次数。若无法通过删除使得矩形被分成至少两个连通块,则输出 -1。
连通块:块内任意两点(可以是同一点)都可以找到至少一条只由上下左右组成的路径相连。
长度为
思路
很容易思考出,答案只有
当
当
当
如果存在,则操作一次即可,否则要操作两次。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
void solve(){
map<int,int>a;
map<int,int>b;
int n,temp;
cin >> n;
vector<int>A(n+1,0);
vector<int>B(n+1,0);
for(int i = 1;i <= n;i++){
cin >> temp;
a[temp] = i;
A[i] = temp;
}
bool ck = false;
for(int i = 1;i <= n;i++){
cin >> temp;
b[temp] = i;
B[i] = temp;
if(abs(i - a[temp]) == 1 || i == a[temp] && i != n && i != 1){
ck = true;
}
}
if(n == 1){
cout << "-1\n";
}else if(n == 2){
if(A[1] == B[1] && A[2] == B[2])cout << "-1\n";
else{
cout << "1\n";
}
}else{
if(ck){
cout << "1\n";
}else{
cout << "2\n";
}
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T;
cin >> T;
while(T--){
solve();
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现