C++日常刷题积累
- 今日刷题汇总 - day025
- 1、笨小猴
- 1.1、题目
- 1.2、思路
- 1.3、程序实现
 
- 2、主持人调度(一)
- 2.1、题目
- 2.2、思路
- 2.3、程序实现
 
- 3、分割等和子集
- 3.1、题目
- 3.2、思路
- 3.3、程序实现 -- 0/1背包问题
 
- 4、题目链接
 
今日刷题汇总 - day025
1、笨小猴
1.1、题目

1.2、思路
读完题知道,处理一组单词,分别统计这组单词中出现次数最多的字母和最少的字母个数maxval和minval,然后判断maxval - minval的差是否是质数,是则输出“Lucky Word”和maxval - minval的差,否则输出“No Answer”和0 即可。根据题目和示例分析,采用hash标记出现单词中字母的个数,然后求得最多和最少个数分别保存在maxval和minval中,然后判断是否是质数,按照要求输出即可。值得注意得是字母最少不是0,质数的判断处理小于2的自然数为flase等细节即可。
1.3、程序实现
#include <iostream>
#include <string>
using namespace std;
int hashch[26];
bool check(int val)
{
    if(val < 2)
        return false;
    for (int i = 2; i < val; i++)
    {
        if (val % i == 0)
            return false;
    }
    return true;
}
int main()
{
    string str;
    cin >> str;
    for (auto ch : str)
    {
        hashch[ch - 'a']++;
    }
    int maxval = -1;
    int minval = 101;
    for (auto num : hashch)
    {
        if (maxval < num)
            maxval = num;
        if (minval > num && num != 0)
            minval = num;
    }
    if (check(maxval - minval))
    {
        cout << "Lucky Word" << endl;
        cout << maxval - minval << endl;
    }
    else
    {
        cout << "No Answer" << endl;
        cout << 0 << endl;
    }
    return 0;
}

 
2、主持人调度(一)
2.1、题目

2.2、思路
读完题知道,对于n个活动,要求只有一个主持人能否完成所有活动且时间不冲突。根据示例和题目分析,如果划分的时间段。前时间段的右区间与后时间段的左区间不冲突即可。即判断考虑后续区间是否能与前⼀个区间重叠,即:schedule[i][0] < schedule[i - 1][1];
2.3、程序实现
class Solution {
public:
    bool hostschedule(vector<vector<int> >& schedule)
    {
        sort(schedule.begin(), schedule.end());
        for(int i = 1; i < schedule.size(); i++)
        {
            //左区间与右区间重叠就false
            if(schedule[i][0] < schedule[i - 1][1]) 
                return false;
        }
        return true;
    }
};

 
3、分割等和子集
3.1、题目

3.2、思路
读完题知道,给定一个只包含正整数的数组 nums ,判断能否把这个数组取出若干个数使得取出的数之和和剩下的数之和相同。在一个限定的数据中,选与不选凑成某种条件,可抽象理解为0/1背包类问题。对于背包问题,在限定的空间内,尽可能选择或不选择对应物品达成存储尽可能地多。而这里是满足选择地数据之和与不选择数据之和相等即可。那么dp动态规划就需要确定状态表示与状态方程,以dp[i][j]表示前 i 个物品中挑选总和恰好为 j 时,能否相等,推导动态转移方程dp[i][j] 对于第 i 个数据选或不选两种情况,且两种情况都可能满足所以将两种情况或起来,第一种不选第 i 位置时,表示在第 i -1 个数中能否凑成 j,即:dp[i][j] = dp[i-1][j],第二种,选择第 i 个数据时,根据前 i-1 个数据的和加上第 i 个位置数据的和恰好凑足 j,即:dp[i][j] = dp[i-1][j-arr[i]].且j 大于 arr[i]。
 综上所示:
 状态表示dp[i][j] :表示前 i 个物品中挑选总和恰好为 j 时,能否凑成相等;
 状态转移方程dp[i][j]:
 a、选择第 i 个位置:dp[i][j] = dp[i][j] || dp[i-1][j-arr[i]];两者满足一个即可,且j > arr[i]
 b、不选择第 i 个位置:dp[i][j] = dp[i-1][j]
 初始化:多开辟一行一列。dp[0][0] = true;
 除此之外,当给的数据之和为奇数时,本身就不满足选择之和等于剩余之和,所以先计算总和sum,判断sum % 2 == 1则返回false即可。
3.3、程序实现 – 0/1背包问题
#include <iostream>
using namespace std;
const int N = 510, M = 510 * 110 / 2;
int n;
int arr[N];
int dp[N][M];
int main() {
    cin >> n;
    int sum = 0;
    for (int i = 1; i <= n; i++)
    {
        cin >> arr[i];
        sum += arr[i];
    }
    if (sum % 2 == 1) 
        cout << "false" << endl;
    else
    {
        sum /= 2;
        dp[0][0] = true;
        for (int i = 1; i <= n; i++)
        {
            for (int j = 0; j <= sum; j++)
            {
                dp[i][j] = dp[i - 1][j];
                if (j >= arr[i])
                {
                    dp[i][j] = dp[i][j] || dp[i - 1][j - arr[i]];
                }
            }
        }
        if (dp[n][sum]) 
            cout << "true" << endl;
        else 
            cout << "false" << endl;
    }
    return 0;
}

 
4、题目链接
🌟笨小猴
 🌟主持人调度(一)
 🌟分割等和子集


















