每日两题day50

明天周末!!!

一、基础题

题目:小红的小小红

思路

先把目标子串输出,然后记录下字符串的所有字符数量并减去已经输出了的字符数量,剩下的直接输出即可

代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define ff first
#define ss second
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    string s;
    cin >> s;
    map<char, int>v;
    for (auto i : s)
    {
        v[i]++;
    }
    string s1 = "xiaohong";
    for (auto i : s1)
    {
        v[i]--;
    }
    cout << s1;
    for (auto i : v)
    {
        for (int j = 1; j <= i.ss; j++)
        {
            cout << i.ff;
        }
    }
}
	

二、提高题

题目:小红构造数组

思路

我们可以先把所有质因数找出来,然后由于相邻的元素不能相同,那么出现最多的质因数的数量不能超过总数量的一半以上(向上取整),否则肯定会存在两个相邻的元素,此时输出 -1,特判 x == 1 的时候也输出 -1,剩下的情况就需要构造出合法数组,我们可以按元素数量从大到小排序,把数量最多的放在奇数下标上,如1、3、5、7,然后接着放置数量第二多的元素,以此类推。如果奇数位放完了,那么从偶数位开始重复以上过程即可,由于出现最多次数的质因数的数量不超过总数量的一半以上(向上取整),那么肯定不会存在重复的相邻元素,时间复杂度 O(√x + k log k)

代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

#define int long long   // 默认整型用 long long
#define endl '\n'
#define ff first
#define ss second

typedef pair<int, int> pii;                     // 整数对类型

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    
    int x;
    cin >> x;           
    
    if (x == 1)         // 如果 x = 1,无法分解
    {
        cout << -1;
        return 0;
    }

    vector<int> cnt;    // 存储 x 的质因数
    int ma = 0;         // 存储某个质因数出现的最大次数
    
    // 分解质因数
    for (int i = 2; i * i <= x; i++)
    {
        int ans = 0;
        while (x % i == 0)   // 统计 i 出现的次数
        {
            x /= i;
            ans++;
            cnt.push_back(i); // 每次出现就加入数组
        }
        ma = max(ma, ans);     // 更新最大次数
    }

    if (x > 1)                 // 剩下的 x 是质数
    {
       cnt.push_back(x);
       ma = max(ma, (int)1);
    }

    // 如果某个质因数次数太多,无法满足要求
    if (ma > (cnt.size() + 1) / 2)
    {
        cout << -1;
    }
    else
    {
        priority_queue<pii> q;              // 大顶堆,存储{次数, 质因数}
        unordered_map<int, int> mp;         // 统计每个质因数的次数

        for (auto i : cnt)
            mp[i]++;

        for (auto i : mp)
            q.push({i.ss, i.ff});           // 次数大的先出堆

        vector<int> a(cnt.size() + 5);      // 存放重排后的质因数
        int l = 1, r = 2;                   // 奇数、偶数位置
        
        // 将质因数按次数安排到数组中,使相同质因数不相邻
        while (q.size())
        {
            int u = q.top().ss;   // 当前质因数
            int ans = q.top().ff; // 当前质因数数量
            q.pop();

            for (int i = 1; i <= ans; i++)
            {
                if (l <= cnt.size())
                {
                    a[l] = u;
                    l += 2;      // 先填奇数位置
                }
                else
                {
                    a[r] = u;
                    r += 2;      // 填偶数位置
                }
            }      
        }

        cout << cnt.size() << endl;         // 输出质因数总个数
        for (int i = 1; i <= cnt.size(); i++)
            cout << a[i] << ' ';           // 输出重排后的质因数
    }
}
相关推荐
txzrxz7 小时前
单调队列讲解
数据结构·c++·算法·单调队列
WWTYYDS_6668 小时前
JsonCpp超详细使用教程
c++
不会就选b8 小时前
算法日常・每日刷题--<快排>4
算法
Keven_118 小时前
算法札记:树状数组的用途
数据结构·算法
Joey_friends8 小时前
指纹authenticate流程图
android·java·c++
用户677437175818 小时前
C++函数参数传递方式详解:string、string&、const string、const string&该怎么选?
算法
小小晓.8 小时前
C++小白记:C风格字符串和数组用法
c语言·开发语言·c++
cpp_25018 小时前
P1540 [NOIP 2010 提高组] 机器翻译
数据结构·c++·算法·队列·noip·洛谷题解
晚笙coding8 小时前
LeetCode 98:验证二叉搜索树 —— 从局部判断到全局范围约束的递归思想
算法·leetcode·职场和发展
学计算机的计算基9 小时前
回溯算法下篇:四道经典题讲透约束剪枝、原地标记、预计算与状态压缩
java·笔记·算法