给定区间 [ l , r ] [l, r] [l,r],让你找到正整数 x x x, y y y满足 l ≤ x < y ≤ r l \leq x < y \leq r l≤x<y≤r,并且 l ≤ l c m ( x , y ) ≤ r l \leq lcm(x, y) \leq r l≤lcm(x,y)≤r
根据题意有:
l ≤ l c m ( x , y ) = x × y g c d ( x , y ) ≤ r l \leq lcm(x,y)=\frac{x \times y}{gcd(x,y)} \leq r l≤lcm(x,y)=gcd(x,y)x×y≤r
l × g c d ( x , y ) x ≤ y ≤ r × g c d ( x , y ) x \frac{l \times gcd(x,y)}{x} \leq y \leq \frac{r \times gcd(x,y)}{x} xl×gcd(x,y)≤y≤xr×gcd(x,y)
其中 l ≤ x < y ≤ r l \leq x < y \leq r l≤x<y≤r
那么显然当 x = g c d ( x , y ) x=gcd(x,y) x=gcd(x,y)时 y y y的范围最大,为 [ l , r ] [l,r] [l,r],即 y y y为 x x x的倍数,则有 y ∣ m i n = 2 x y|_{min}=2x y∣min=2x
所以我们令 x = l x=l x=l, y = 2 x y=2x y=2x,若 y > r y>r y>r,则无解
时间复杂度 O ( 1 ) O(1) O(1)
#include
using namespace std;
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int T;
cin >> T;
while (T--) {
int l, r;
cin >> l >> r;
if (r >= l * 2) cout << l << " " << l * 2 << '\n';
else cout << "-1 -1\n";
}
return 0;
}
有一个序列 a a a,你初始位置为 1 1 1,你必须移动 k k k次,每次可以向左或向右移动一格,并获得所在位置的分数,要求是你不能连续向左移动,并且向左移动次数不能大于 z z z,问你获得的最大分数为多少
首先我们需要明确以下三点:
想清楚以上三点事情就简单了,我们可以枚举终点 i i i,计算其得分的最大值,显然 i ∈ [ k − 2 z − 1 , k + 1 ] i \in [k-2z-1,k+1] i∈[k−2z−1,k+1]( k − ( i + 1 ) ≥ 2 z k-(i+1) \geq 2z k−(i+1)≥2z)
对于终点 i i i,我们向右的基础次数是 i + 1 i+1 i+1,那么向左的次数 z z zz zz则为 k − ( i + 1 ) k-(i+1) k−(i+1),若 z z zz zz为偶数,我们就可以选择 j ∈ [ 1 , i ] j \in [1,i] j∈[1,i]中 a [ j ] + a [ j − 1 ] a[j]+a[j-1] a[j]+a[j−1]最大的地方来回跑,此时 p o i n t = ( max j = 1 i ( a j + a j + 1 ) ) × k − ( i + 1 ) 2 + ∑ j = 1 i a i point=(\max_{j=1}^{i}(a_{j}+a_{j+1}))\times \frac{k-(i+1)}{2}+\sum_{j=1}^{i}a_{i} point=(maxj=1i(aj+aj+1))×2k−(i+1)+∑j=1iai,否则若 z z zz zz为奇数,那么我们只能在 i i i和 i − 1 i-1 i−1之间来回跑,最后停在 i − 1 i-1 i−1位置,此时 p o i n t = ( a i + a i − 1 ) × k − ( i + 1 ) − 1 2 + a i − 1 + ∑ j = 1 i a i point=(a_{i}+a_{i-1})\times \frac{k-(i+1)-1}{2}+a_{i-1}+\sum_{j=1}^{i}a_{i} point=(ai+ai−1)×2k−(i+1)−1+ai−1+∑j=1iai
max j = 1 i \max_{j=1}^{i} maxj=1i和 ∑ j = 1 i a i \sum_{j=1}^{i}a_{i} ∑j=1iai显然可以预处理,那么时间复杂度为 O ( n ) O(n) O(n)
#include
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
int a[maxn], b[maxn], sum[maxn];
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
register int T;
cin >> T;
while (T--) {
memset(b, 0, sizeof(b));
register int n, k, z;
cin >> n >> k >> z;
for (int i = 1; i <= n; ++i) {
cin >> a[i];
sum[i] = sum[i - 1] + a[i];
}
int Max = 2;
for (int i = 2; i <= n; ++i) {
if (a[i - 1] + a[i] > a[Max - 1] + a[Max]) {
b[i] = i - 1;
Max = i;
}
else b[i] = Max - 1;
}
int res = 0;
for (int i = 2; i <= k + 1; ++i) {
int zz = k - i + 1;
if (zz > z * 2) continue;
if ((zz & 1) == 0) {
res = max(res, (a[b[i]] + a[b[i] + 1]) * (zz / 2) + sum[i]);
}
else {
res = max(res, (a[i] + a[i - 1]) * (zz / 2) + sum[i] + a[i - 1]);
}
}
cout << max(res, sum[k + 1]) << '\n';
}
return 0;
}
给你一个字符串 s s s,让你从中删去一些字符变成 t t t使得 t n t 1 t 2 . . . t n − 1 = t 2 t 3 . . . t n t 1 t_{n}t_{1}t_{2}...t_{n-1}=t_{2}t_{3}...t_{n}t_{1} tnt1t2...tn−1=t2t3...tnt1,问你删去字符的最少数量是多少
手动模拟一下
当 n = 2 n=2 n=2时, t 2 t 1 = t 2 t 1 t_{2}t_{1}=t_{2}t_{1} t2t1=t2t1显然成立
当 n = 3 n=3 n=3时, t 3 t 1 t 2 = t 2 t 3 t 1 t_{3}t_{1}t_{2}=t_{2}t_{3}t_{1} t3t1t2=t2t3t1需要满足 t 1 = t 2 = t 3 t_{1}=t_{2}=t_{3} t1=t2=t3
当 n = 4 n=4 n=4时, t 4 t 1 t 2 t 3 = t 2 t 3 t 4 t 1 t_{4}t_{1}t_{2}t_{3}=t_{2}t_{3}t_{4}t_{1} t4t1t2t3=t2t3t4t1需要满足 t 1 = t 3 , t 2 = t 4 t_{1}=t_{3},t_{2}=t_{4} t1=t3,t2=t4
当 n = 5 n=5 n=5时, t 5 t 1 t 2 t 3 t 4 = t 2 t 3 t 4 t 5 t 1 t_{5}t_{1}t_{2}t_{3}t_{4}=t_{2}t_{3}t_{4}t_{5}t_{1} t5t1t2t3t4=t2t3t4t5t1需要满足 t 1 = t 2 = t 3 = t 4 = t 5 t_{1}=t_{2}=t_{3}=t_{4}=t_{5} t1=t2=t3=t4=t5
当 n = 6 n=6 n=6时, t 6 t 1 t 2 t 3 t 4 t 5 = t 2 t 3 t 4 t 5 t 6 t 1 t_{6}t_{1}t_{2}t_{3}t_{4}t_{5}=t_{2}t_{3}t_{4}t_{5}t_{6}t_{1} t6t1t2t3t4t5=t2t3t4t5t6t1需要满足 t 1 = t 3 = t 5 , t 2 = t 4 = t 6 t_{1}=t_{3}=t_{5},t_{2}=t_{4}=t_{6} t1=t3=t5,t2=t4=t6
. . . ... ...
那么规律已经很明显了,我们可以取 s s s中出现最多的字母,或者取两个不同的字母分别放在奇数位和偶数位上,前提是这两个字母在原字符串中需要满足相应的次序关系,由于字母只包含 0 ∼ 9 0 \sim 9 0∼9,我们可以暴力枚举这两个数字,总复杂度为 O ( 100 × n ) O(100\times n) O(100×n)
需要注意的是可保留的字符数最少为 2 2 2
#include
using namespace std;
typedef long long ll;
int num[15];
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int T;
cin >> T;
while (T--) {
memset(num, 0, sizeof(num));
string s;
cin >> s;
int len = s.length();
int Max = 2;
for (int i = 0; i < len; ++i) {
int ch = s[i] - '0';
++num[ch];
Max = max(Max, num[ch]);
}
for (int i = 0; i <= 9; ++i) {
for (int j = 0; j <= 9; ++j) {
if (i == j) continue;
int cnt = 0;
for (int k = 0; k < len; ++k) {
int ch = s[k] - '0';
if ((cnt & 1) == 0 && ch == i) ++cnt;
else if ((cnt & 1) && ch == j) ++cnt;
}
Max = max(Max, (cnt / 2) * 2);
}
}
cout << len - Max << '\n';
}
return 0;
}