A 区间最大值
题意:
长度为 n 的数组 a,下标从1开始,定义 a[i]=n%i,有m次询问,每个询问给你l和r,判断l和r中a[i]的最大值。
分析:板子题,数论分块。n mod i = n - (n/i) *i。
题解:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n, m;
cin>> n >> m;
while(m--)
{
int l, r;
cin >> l >> r;
int ans = 0;
for (int i = l; i <= r; i = n / (n / i) + 1)
{
ans = max(ans, n % i);
}
cout << ans << endl;
}
}
B 模块改造
题意:给你一个长度为48的01段,每个字符顺序对应24小时中的半个小时。问在哪些时间里为‘1’,如果没有输出00:00 - 00:00。
分析:简单的模拟,使用一个cnt记录连续的几个‘1’,当遇到0输出当前的连续的时间,最后也判断输出一下,另外特判全零的情况。
题解:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
string s;
int cnt = 0, p;
bool f = 0;
int main()
{
cin >> s;
for(int i=0;i<48;i++)
{
if(s[i]=='1')
cnt++;
else
{
if(cnt)
{
p = i - cnt - 1;
printf("%02d:%02d", (p + 1) / 2, (p + 1) & 1 ? 30 : 00);
cout << " - ";
printf("%02d:%02d\n", i / 2, i & 1 ? 30 : 00);
f = 1;
}
cnt = 0;
}
}
if(cnt)
{
{
p = 48 - cnt - 1;
printf("%02d:%02d", (p + 1) / 2, (p + 1) & 1 ? 30 : 00);
cout << " - ";
printf("%02d:%02d\n",48 / 2, 48 & 1 ? 30 : 00);
f = 1;
}
}
if(!f) cout << "00:00 - 00:00\n";
return 0;
}
I V字钩爪
题意:n堆宝石,给你长度为k的v型钩子,可以抓取i和i + k的两颗宝石,必须两边都有宝石,求任意抓取最终得到的最大价值是多少。
分析:数字序列下表从0开始,按照下表mod k分组,对于每一个分组,如果组数为偶数,就可以拿走所有的数;如果组数为奇数,就必须舍弃奇数位上一个数字。
题解:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[1000010];
int main()
{
int n, k;
cin >> n >> k;
for(int i=1;i<=n;i++)
cin >> a[i];
ll sum = 0;
for(int i=1;i<=k;i++)
{
int cnt = 0;
int minn = 0x7fffffff;
for(int j=i;j<=n;j+=k)
{
cnt++;
if(cnt&1) minn = min(minn, a[j]);
sum += a[j];
}
if(cnt&1)
sum -= minn;
}
cout << sum << endl;
}