【刷题汇总 -- 小乐乐改数字、十字爆破、比那名居的桃子】

今日刷题汇总 - day017

1、小乐乐改数字

1.1、题目

在这里插入图片描述

1.2、思路

读完题,知道需要将一个整数的每一位进行转换,如果是偶数转换为0,若是奇数转换为1,如果全是偶数则去掉前导0即可。基本思路就是去摸获取每一位,进行奇偶性判断,进行相应的转换,然后将转换后的值,由于位置不变,进行位数等价求和即可。另外,也可以使用字符串的思维,虽然是让输入一个整数,但是以字符串的方式输入整数,直接就方便遍历,并且赋值0/1,最后转回整数输出即可。那么,接下来就是程序实现。

1.3、程序实现 – 蛮力法

首先,按照题目要求输入一个整数n,利用循环去取模依次获取这个数的低位,进行奇偶性判断,然后利用pow还原位数关系即可。

#include <iostream>
#include <cmath>
using namespace std;

int main()
{
    int n;
    cin >> n;
    int ret = 0;
    int i = 0;
    while(n)
    {
        int temp = n % 10;
        if(temp % 2 == 0)
        {
            temp = 0;
        }
        else
        {
            temp = 1;
        }
        ret += temp*pow(10,i++);
        n /= 10;
    }
    cout << ret << endl;
    return 0;
}

在这里插入图片描述
在这里插入图片描述

1.4、程序实现 – 字符串优化

然后对于字符串的方式就更加方便了,直接遍历转换奇偶数即可,最后利用stoi转回int整数型即可。

#include <iostream>
#include <string>
using namespace std;

int main()
{
    string str;
    cin >> str;
    for(int i = 0;i < str.size();i++)
    {
        if(str[i] % 2 == 0)
        {
            str[i] = '0';
        }
        else
        {
            str[i] = '1';
        }
    }
    cout << stoi(str) << endl;//自动能处理前导0
    return 0;
}

在这里插入图片描述
在这里插入图片描述

2、十字爆破

2.1、题目

在这里插入图片描述

2.2、思路

读完题知道,让处理一个n*m的方格中,可任意选择一个方格的数字,可求得该方格的同行、同列的数字之和,最后要求选择每一个方格的所有得分情况并且输出。那么,分析示例和题目可知道由于数据量过⼤,我们可以提前把每⼀⾏以及每⼀列的和存起来,⽅便统计总和。这样处理之后就发现,对于题目中的示例为例:row[0] = 1+2 = 3; col[0] = 1 + 3 = 4;然后得到row[0] + col[0] = 3 + 4 = 7;对于arr[0][0]加了两次,所以再将arr[0][0]剪掉多余的一次得到7 - 1 = 6.就是该方格所得的分数。再对于示例1为例:row[0] = 2 + 2 = 4;col[0] = 2 + 1 + 3 = 6; row[0] + col[0] = 4 + 6 = 10;然后arr[0][0]出现了两次,把多余的arr[0][0] = 2减去 = 2 + 2 + 1 + 3 = 8; 那么接下来,就是程序实现。

2.3、程序实现

首先,按照题目要求输入数据n,m,然后定义需要的行、列数组,row和col,然后输入n*m方阵数据并同时预处理将每一行和每一列的和提前求出,然后遍历方阵减掉多余加的一次方格的值即可。

#include <iostream>

using namespace std;

const int N = 1e6 + 10;
long long row[N], col[N];

int main()
{
    long long n,m;
    scanf("%lld %lld", &n, &m);
    long long arr[n][m];
    
    for(int i = 0;i < n;i++)
    {
        for(int j = 0;j < m;j++)
        {
            scanf("%lld", &arr[i][j]);
             row[i] += arr[i][j];
             col[j] += arr[i][j];
        }
    }
    
    for(int i = 0; i < n; i++)
     {
         for(int j = 0; j < m; j++)
         {
             printf("%lld ", row[i] + col[j] - arr[i][j]);
         }
         printf("\n");
     }
    return 0;
}

在这里插入图片描述
在这里插入图片描述

3、比那名居的桃子

3.1、题目

在这里插入图片描述

3.2、思路

读完题知道,处理小红桃子的快乐值与羞耻值之间的关系,除此之外,存在两个特殊情况,如果有多个答案获得的快乐值相等,小红希望获得尽可能少的羞耻度。如果有多个答案的快乐值和羞耻度都相等,由于小红实在太想吃桃子了,她希望尽可能早的吃下桃子。另外,两个正整数 n 和 k ,分别代表桃子的有效期总天数,以及桃子效果的持续天数。可以理解为桃子腐烂的总天数为n,k表示吃下桃子在k天范围内的持续天数,不就想到了滑动窗口的思想了吗?利用两个指针遍历这个桃子的情况,维护长度/大小/天数为k的窗口即可,那么目前想到采用滑动窗口,基本步骤如下:
(1)、进窗口
(2)、判断窗口
(3)、出窗口
(4)、更新结果
那么接下来就是程序实现。

3.3、程序实现 – 滑动窗口

根据思路分析,利用滑动窗口维护窗口可枚举到最多快乐值,最少羞耻值,得到合适吃下的天数。
采用滑动窗口,推导基本步骤如下:
(1)、进窗口:累加快乐值和羞耻值分别保存在变量happySum和shySum中;
(2)、判断窗口:当窗口大小超过k天的大小时,就滑动窗口left++;
(3)、出窗口:减去left下标处的快乐值和羞耻值。
(4)、更新结果:当窗口大小等于k天的大小时,就更新最大快乐值和最少羞耻值
那么先按照题目要求(也就是数据范围等)写好输入数据n,k快乐值和羞耻值,接着定义所有需要的变量left 、right左右指针维护窗口大小,happySum 和 shySum统计窗口中快乐值和羞耻值的和,然后hMax 与 sMin保存最大快乐值和最小羞耻值,最后一个suitable_day 表示最合适的第几天。然后搭建后滑动窗口框架。

#include <iostream>
using namespace std;

const int N = 1e5 + 10;
long long n,k;
long long h[N];
long long s[N];

int main()
{
    cin >> n >> k;
    for(int i = 1;i <= n;i++)
        cin >> h[i];
    for(int i = 1;i <= n;i++)
        cin >> s[i];
  
    long long left = 0;
    long long right = 0;
    long long happySum = 0;
    long long shySum = 0;
    long long hMax = 0;
    long long sMin = 0;
    long long suitable_day = 0;
    
    while(right <= n)
    {
        //进窗口
        
        //判断窗口 - 出窗口
        
        //判断窗口 - 更新结果
        
    }
    cout << suitable_day << endl;  
    return 0;
}

接着继续完善滑动窗口的程序,将窗口中的快乐值和羞耻值进窗口累计到happySum 和 shySum中,然后,判断窗口 - 是否需要出窗口,如果需要出窗口则将左指针的快乐值与羞耻值处窗口,同时left++,滑动窗口至下一组窗口位置,判断窗口是否需要更新结果,如果需要则更新最大快乐值,更新suitable_day 至left下标的天数,同时考虑题目中提到了特殊情况,如果有多个答案获得的快乐值相等,小红希望获得尽可能少的羞耻度,更新羞耻度和suitable_day至left下标的天数 ,第二个特殊情况,尽可能早的吃,本身逻辑就是一次枚举所以自然满足尽早的要求了。最后输出suitable_day 即可。

#include <iostream>
using namespace std;

const int N = 1e5 + 10;
long long n,k;
long long h[N];
long long s[N];

int main()
{
    cin >> n >> k;
    for(int i = 1;i <= n;i++)
        cin >> h[i];
    for(int i = 1;i <= n;i++)
        cin >> s[i];
  
    long long left = 0;
    long long right = 0;
    long long happySum = 0;
    long long shySum = 0;
    long long hMax = 0;
    long long sMin = 0;
    long long suitable_day = 0;
    
    while(right <= n)
    {
        //进窗口
        happySum += h[right];
        shySum += s[right];
        //判断窗口 - 出窗口
        while(right - left + 1 > k)
        {
            happySum -= h[left];
            shySum -= s[left];
            left++;
        }
        //判断窗口 - 更新结果
        if(right - left + 1 == k)
        {
            if(hMax < happySum)//更新最大快乐值与结果
            {
                hMax = happySum;
                sMin = shySum;
                suitable_day = left;
            }
            else if(happySum == hMax && shySum < sMin)//更新最小羞耻值与结果
            {
                hMax = happySum;
                sMin = shySum;
                suitable_day = left;  
            }
        }
        right++;
    }
    cout << suitable_day << endl;  
    return 0;
}

在这里插入图片描述
在这里插入图片描述

4、题目链接

🌟小乐乐改数字
🌟十字爆破
🌟比那名居的桃子

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值