A题 解题思路:
输入 n ,d 求数组中,删除多少数后剩下的数组中的最大值与最小值的差值 <= d。求删除的最小数目。
一开始想到双指针,结果真的是想多了(该暴力的时候不暴力) ,n 的大小不超过200 ,n^2 暴力就OK,记得提前排下序,找到符合的最大长度,最后用 n - 最大长度即可。
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int ans[10005];
int main(){
int n , d;
scanf("%d%d",&n,&d);
for (int i = 0; i < n; i ++){
scanf("%d",&ans[i]);
}
int mx = 0;
sort(ans,ans + n);
for (int i = 0; i < n; i++){
for (int j = 0 ; j <= i; j ++){
if (ans[i] - ans[j] <= d){
mx = max(mx,i - j + 1);
}
}
}
printf("%d\n",n - mx);
return 0;
}
给予n , a, b, k 求从n走到 1话费最少的钱数,有两种走路方法,一种是 一下走一步,另一种是一下到 n / k 步,但必须能被 k 整除。
第一种话费 a 钱 ,第二种话费 b 钱。
因此我们可以选择走一步或者一下走多部。(直接在代码注释中阐明)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
int main(){
long long n, k , a ,b; //注意数据范围
cin>>n>>k>>a>>b;
long long res = 0;
while (n != 1){
if (n % k == 0){ //如果整除,那么可以选择一下走到 n/k 步
long long t = n / k;
if (b >= (n - t) * a){ // 如果一下跳多步所花的钱数都没一步花的钱数少,那么后面的肯定都是一步一步走
res += (n - 1) * a;
break;
}
else{ //如果比一步一步花的钱数多,那么我们一次性走到 n / k 处
res += b;
n = t;
}
}
else{ // 如果不能整除
res += (n % k ) *a; // 那么直接计算到能整除时候的位置 进行 % 运算 (原先一步一步走,结果超时了)
n -= n % k;
}
}
cout<<res<<endl;
return 0;
}
给予n , k 然后给出长度为 n 的字符串,让我们求出长度为 k 的字符串 让他的字典序比给定的字符串大,在这个要求下,让他最小。(字符只能用题目给定字符串中的字符)
分为两种情况:
- 当 k > n 时: 我们之间在原给的字符串中加入k - n 个原给字符串中的最小字母。
- n >= k 那么我们截取长度为 n 的前 k 个字符,从后向前找,找出第一个不是最大字符的字符位置,将其变为比他大一的字符,然后后面位置的字符全都改成最小的字符。
(这里的最大最小都是根据给定的原本字符串含有的字符定义的大小)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
char ans[30];
int main(){
int n , k;
cin>>n>>k;
string St;
cin>>St;
string St1 = St;
sort(St1.begin(),St1.end());
int m = 0;
ans[m] = St1[0];
for (int i = 1; i < n ; i ++){
if (ans[m] != St1[i]){
ans[++m] = St1[i];
}
}
if (k > n){
for (int i = 0; i < n; i ++){
printf("%c",St[i]);
}
for (int i = 0; i < k - n; i++){
printf("%c",ans[0]);
}
printf("\n");
}
else{
string St2 = "";
for (int i = 0; i < k ;i++){
St2 += St[i];
}
for (int i = k - 1; i >= 0; i --){
char s = St[i];
if (s != ans[m]){
for (int j = m - 1; j >= 0; j--){
if (ans[j] == s){
St2[i] = ans[j + 1];
for (int q = i + 1; q < k ; q ++){
St2[q] = ans[0];
}
cout<<St2<<endl;
return 0;
}
}
}
}
}
return 0;
}
给予一个n,然后给予一个长度为 n 的 数组a ,然后给予一个长度为 n 的字符串 b。
题目中说明:
因此当 i >= 5时候,我们判断 b字符串中 i 位置的数是否和前一个相同:
- 如果相同:那么继续进行
- 如果不同:那么判断他的前四个是否相等,如果相等,并且为 1 那么执行第一个操作,如果为2,那么进行第二个操作,否则什么都不进行
然后循环就OK,本题是随意输出结果 (只要符合答案就OK)
初值很重要,-1e9 和 1e9 ,最后不要忘记 + 1 和 - 1 因为是 大于号和小于号。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 500010;
int ans[N];
int main(){
int n;
scanf("%d",&n);
for (int i = 0; i < n; i++){
scanf("%d",&ans[i]);
}
string b;
cin>>b;
int l = -1e9;
int r = 1e9;
for (int i = 4; i < n ;i++){
if (b[i] != b[i - 1]){
if (b[i - 1] == b[i - 2] && b[i - 2] == b[i -3] && b[i - 3] == b[i - 4]){
if (b[i - 4] == '0') {
for (int j = i - 4; j <= i; j ++){
l = max(l,ans[j]);
}
}
else{
for (int j = i - 4; j <= i; j++){
r = min(r,ans[j]);
}
}
}
}
}
printf("%d %d\n",l + 1,r - 1);
return 0;
}