牛客周赛 Round 99

赛时成绩如下:

A. Round 99

题目描述

对于给定的五位整数,检查其中是否含有数字 99;换句话说,检查是否存在相邻的两个数位,其值均为 。
解题思路: 检查相邻的两个数字是否均为9

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pll = pair<ll, ll>;
void solve() {
    int n;
    cin >> n;
    string a = to_string(n);
    for (int i = 1; i < a.size(); i++) {
        if (a[i] == a[i - 1] && a[i] == '9') {
            cout << "YES" << '\n';
            return;
        }
    }
    cout << "NO" << '\n';
}
int main() {
    int t = 1;
    // cin>>t;
    while (t--) {
        solve();
    }
    return 0;
}

B. 缺陷型电脑

题目描述

Tk 有一台缺陷型电脑,它在输出内容之前必须先加载 ASCII 表;

这台电脑可以为每次输入生成一个长度为 x 的 ASCII 表,该表包含编码值从 1 到 x 的所有字符;

现在给定一个仅由++可见字符++集合构成的字符串 s。请你计算:要输出 s 中的所有字符,至少需要多长的 ASCII 表。

【名词解释】

可见字符集为 ASCII 码在 33 到 126 范围内的可见字符。您可以参阅下表获得其详细信息(您可能关注的内容是,这其中不包含空格、换行)。
解题思路:包含从1-x的所有字符, 同时表的长度为x

因此, 直接找出输入字符中最大的即为答案

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pll = pair<ll, ll>;
void solve() {
    int n;
    string s;
    cin >> n >> s;
    int mx = *max_element(s.begin(), s.end());
    cout << mx << '\n';
}
int main() {
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}

C.小苯的洞数构造

解题思路:

小苯对数字的 "洞数" 十分感兴趣,即数字中含有的封闭图形个数,如下是每个数位的 "洞数" 表:

现在小苯给定了一个整数 k,他希望你构造一个值最小的,满足所有数位中的 "洞数" 总和恰好为 k 的正整数(不包含前导 0 ),请你帮帮他吧。
解题思路:

满足由洞数构造出的值最小

1 洞:4, 6, 9

2 洞:8

0 洞:1, 2, 3, 5, 7

为了让生成的正整数数值最小,第一要点是"尽量少的位数"------位数少的数值更小

"8"有 2 个洞,用它能最快凑洞数,减少总位数

余下的 1 个洞(如果目标洞数为奇数),用"4"来补;虽然"0"也是 1 洞,但不能出现在首位;在多位数里放"4"比放"6""9"都更小

特殊情况

当 𝑘=0

k=0 时,需要一个"零洞"且最小的正整数,显然是 "1"

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pll = pair<ll, ll>;
void solve() {
    int k;
    cin >> k;
    if (k == 0) {
        cout << 1 << '\n';
        return;
    }
    int cnt = k / 2;
    if (k & 1) {
        cout << 4;
    }
    for (int i = 0; i < cnt; i++) {
        cout << 8;
    }
    cout << '\n';
}
int main() {
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}

D. 前缀和

题目描述

小红有一个由正整数组成的数组 a,但是她没有告诉你数组中的元素具体是什么,你只知道这个数组的元素各不相同,且其前缀数组 s 对于给定的一个 x,其任意一项均满足:,∙对于数组的第 k 个元素,当 ⌊kx⌋ 为偶数时,sk=a1+a2+⋯+ak​ 也是偶数;

,∙对于数组的第 k 个元素,当 ⌊kx⌋ 为奇数时,sk=a1+a2+⋯+ak 也是奇数。

除此之外,你还知道这个数组是满足条件的所有数组中++字典序++ 最小的。小红现在来问你,这个数组中第 p 个元素是多少,你能快速的回答她吗?

【名词解释】

字典序:从两个数组的第一个元素开始逐个比较,直到找到第一个不同的元素,较小元素所在的数组的++字典序++较小。
解题思路: 以x为周期, 前面全是偶数, 最后一位是奇数

计算 a = ⌊p/x⌋:

这表示 p 所在的"块"编号(每 x 个元素为一组)

判断 p 是否是 x 的倍数:

如果 p % x == 0,说明 p 是当前块的最后一个元素

否则,p 位于块的中间

计算 a[p]:

如果 p 是块的最后一个元素(p % x == 0),则 a[p] = 2a - 1

否则,a[p] = 2(p - a)

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pll = pair<ll, ll>;
void solve() {
    ll x, p;
    cin >> x >> p;
    ll a = p / x;
    if (p % x == 0) {
        cout << 2 * a - 1 << '\n';
    } else {
        cout << 2 * (p - a) << '\n';
    }
}
int main() {
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}

E. 小宇

题目描述

给定一个长度为 n 的数组 {a1,a2,...,an}。

你可以进行以下操作多次:

,∙选择一个整数 x,将所有满足 ai=x 的元素分别修改为它们的下标 i;

问 最少需要进行多少次操作,才能使数组变为严格单调递增?

严格单调递增:若数组 {b1,b2,...,bn} 对任意下标 i<ji<ji<j 都满足 bi<bj,则称其为严格单调递增数组。
解题思路:

首先经过观察可知,每个位置的数字一定不小于它的下标,且若进行了修改,一定是对一段前缀进行修改,因此只需要从后往前找到第一个需要修改的位置,并把前缀里面所有出现过的数字的值的出现的最大下标范围内的数字都进行修改即可,注意,根据修改规则和分析,只需修改那些值不等于下标的位置即可,可用set去重

java 复制代码
public class Main{
    public static void main(String args[]){
        Scanner sc=new Scanner(System.in);
        for(int i=sc.nextInt();i!=0;i--){
            int n=sc.nextInt(),a[]=new int[n+5],maxIdx=0;
            Map<Integer,Integer> map=new HashMap<>();
            for(int j=1;j<=n;j++){
                a[j]=sc.nextInt();
                map.put(a[j],Math.max(j,map.getOrDefault(a[j],0)));
            }
            a[n+1]=(int)2e9;
            for(int j=n;j>0;j--){
                if(a[j]>=a[j+1]||a[j]<j){
                    for(int k=1;k<=j;k++){
                        if(a[k]!=k){
                            maxIdx=Math.max(maxIdx,map.get(a[k]));
                        }
                    }
                    break;
                }
            }
            Set<Integer> set=new HashSet<>();
            for(int j=1;j<=maxIdx;j++){
                if(a[j]!=j){
                    set.add(a[j]);
                }
            }
            System.out.println(set.size());
        }
    }
}

F. 汉堡猪猪分糖果

题目描述

汉堡猪猪有 n 颗糖果,他想把糖果全部分给 m 个小朋友。

每个小朋友至少要分到一颗糖果,否则他们会生气。他想知道,如何分配才能让所有小朋友分到的糖果数量的 按位与最大?
解题思路:

1.贪心策略:

从高位到低位检查,优先保证高位的 1,因为高位的 1 对结果的影响更大

如果能分配所有小朋友的某一位为 1,就直接分配;否则,尝试部分分配

2.对于每一位 j,计算分配 1 的最小糖果数 (1 << j) * m

如果糖果不足,尝试部分分配,确保剩余的糖果可以满足其他约束

java 复制代码
import java.util.*;
public class Main{
    public static void main(String args[]){
        Scanner sc=new Scanner(System.in);
        for(int i=sc.nextInt();i!=0;i--){
            long n=sc.nextInt(),m=sc.nextInt(),ans=0;
            for(int j=30;j>=0;j--){
                long cur=(1L<<j)*m;
                if(n>=cur){
                    //这一位可以全是1
                    n-=cur;
                    ans|=1<<j;
                }
                else{
                    cur-=m;
                    //先测试一下可否后边全为1
                    if(n>cur){
                        //说明这一位后边全为1的话,还有剩余,导致后边的数字不应定按位与得到全1,那就想办法使得后边的数字尽可能大
                        //n-k*(1<<j)<=cost
                        n-=(1<<j)*((n-cur-1)/(1<<j)+1);
                    }
                }
            }
            System.out.println(ans);
        }
    }
}

感谢大家的点赞和关注,你们的支持是我创作的动力!

相关推荐
小何好运暴富开心幸福5 分钟前
分层架构的C++高并发内存池性能优化
c++·性能优化·架构
逑之9 分钟前
排序算法:快排的深入优化和文件归并
算法·排序算法
封印师请假去地球钓鱼19 分钟前
粒子滤波|粒子滤波算法介绍
算法
码银29 分钟前
基于Java的Markdown到Word文档转换工具的实现
java·word
皮卡蛋炒饭.30 分钟前
数据结构——堆
数据结构·算法
汉克老师36 分钟前
GESP2025年6月认证C++三级( 第三部分编程题(1)奇偶校验)
c++·gesp三级·gesp3级
JuneXcy42 分钟前
第七章应用题
数据结构
教练、我想打篮球1 小时前
68 指针的减法操作
c++·c·struct
Mr_Xuhhh1 小时前
QWidget的属性
java·数据库·c++·qt·系统架构
harykali1 小时前
Datawhale AI 夏令营:Task2从MCP入门到MCP Sever设计
算法·mcp