C++日常刷题积累
今日刷题汇总 - 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;
}