一、3790.录入单词(简单)
任意门
小明在电脑上持续录入 n 个单词。
其中,第 i 个单词在第 ti 秒录入电脑。
一个单词录入完毕后,如果连续 c 秒都没有录入新的单词,则屏幕将会刷新,屏幕中所有单词都被清空。
具体来说,如果前一个单词在第 a 秒录入,后一个单词在第 b 秒录入,那么:
如果 b−a≤c,则将后一个单词附加到屏幕中其他单词的后面。
如果 b−a>c,则前面的所有单词都会消失,屏幕中只会保留最后一个单词。
请你计算,当所有单词录入完毕时,屏幕中共有多少个单词。
例如,当 n=6,c=5,每个单词的录入时间依次为 1,3,8,14,19,20 时,注意以下几个时间点:
第 8 秒时,屏幕中有三个单词。
第 13 秒时,屏幕中所有单词清空。
第 14 和 19 秒,屏幕中各添加一个单词。
第 20 秒时,屏幕再添一个单词,全部单词录入完毕,此时屏幕中共有 3 个单词。
输入格式
第一行包含两个整数 n 和 c。
第二行包含 n 个整数 t1,t2,…,tn。
输出格式
输出一个整数,表示当所有单词录入完毕时(即第 tn 秒时),屏幕中存在的单词数量。
数据范围
1≤n≤105,
1≤c≤109,
1≤t1<t2<…<tn≤109。
输入样例1:
6 5
1 3 8 14 19 20
输出样例1:
3
输入样例2:
6 1
1 3 5 7 9 10
输出样例2:
2
由于n是 1 0 5 10^5 105,所以要把时间复杂度控制在 O ( n log n ) O(n\log_n) O(nlogn)以内
#include<bits/stdc++.h>
using namespace std;
int n,c;
const int N=100010;
int a[N];
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n>>c;
cin>>a[0];
int ans=0;
for(int i=1;i<n;i++)
{
cin>>a[i];
if(a[i]-a[i-1]>c)
ans=0;
else ans++;
}
ans++;
cout<<ans<<endl;
return 0;
}
这里其实也可以不用数组,因为他只用管当前输入的数和上一个输入的数,直接用两个常量来维护一下即可。
二、3791. 解码(模拟)
定义一个单词中位于最中间的字母为中心字母。
如果单词的长度为偶数,则中心字母定义为中间两个字母中靠左的那个。
如果单词的长度为 1,则中心字母是它本身。
一种单词加密方式为:
记录单词的中心字母,并将该字母在单词中删除。
不断重复上述操作,直至单词被完全删除。
将记录下的字母依次连接,得到加密后的单词。
例如,volga 经过加密可以得到 logva。
现在,给定一个加密后的单词,请你求出原单词。
输入格式
第一行包含整数 n,表示单词长度。
第二行包含一个长度为 n 的小写字母构成的字符串表示加密后的单词。
输出格式
输出原单词。
数据范围
1≤n≤2000
输入样例1:
5
logva
输出样例1:
volga
输入样例2:
2
no
输出样例2:
no
输入样例3:
4
abba
输出样例3:
baba
题意:
告诉你了一个加密过后的单词,然后让你求原来的单词
思路:
这一题数据范围比较小,可以直接模拟
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
int main()
{
int n;
string a,b;
cin>>n>>a;
b=a;
vector<int>p;//这一题用的是vector来存储
for(int i=0;i<n;i++)
p.push_back(i);//简单的记录有多少个元素而已
for(int i=0;i<n;i++)
{
int t=(p.size()-1)/2;
b[p[t]]=a[i];
p.erase(p.begin()+t);
}
cout<<b<<endl;
return 0;
}
这一题于我的意义所在可能就是加强了对vector的使用上面了。
三、3793. 最大分数(签到题类型)
给定 n 个整数 a1,a2,…,an。
请你从中选取最多不超过 m 个数(也可以什么都不选)。
选取正数将会扣除相应值的分数,选取负数将会得到相应值的绝对值的分数,选取 0 不得分也不扣分。
请计算可以获得的最大分数。
输入格式
第一行包含整数 T,表示共有 T 组测试数据。
每组数据第一行包含两个整数 n,m。
第二行包含 n 个整数 a1,a2,…,an。
输出格式
每组数据输出一行结果,表示最大分数。
数据范围
1≤T≤20,
1≤m≤n≤100,
−1000≤ai≤1000
输入样例:
5
5 3
-6 0 35 -2 4
4 2
7 0 0 -7
6 6
756 -611 251 -66 572 -818
5 5
976 437 937 788 518
5 3
-2 -2 -2 -2 -2
输出样例:
8
7
1495
0
6
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int N=110;
int n,m;
int w[N];
int main()
{
int T;
cin>>T;
while(T--)
{
cin>>n>>m;
int k=0;
for(int i=0;i<n;i++)
{
int x;
cin>>x;
if(x<0)
w[k++]=-x;
}
sort(w,w+k,greater<int>());//让他从大到小去排序
int res=0;
for(int i=0;i<m&&i<k;i++)
res+=w[i];
cout<<res<<endl;
}
return 0;
}
四、3792. 质数问题(素数筛+暴力枚举)
任意门
给定两个整数 n 和 k,请你判断在 [2,n] 的范围内是否存在不少于 k 个质数,满足可以表示为两个相邻质数与 1 的和。
例如,19 满足条件,因为 19=7+11+1。
输入格式
第一行包含整数 T,表示共有 T 组测试数据。
每组数据占一行,包含两个整数 n 和 k。
输出格式
每组数据输出占一行,如果存在不少于 k 个质数满足条件则输出 YES,否则输出 NO。
数据范围
1≤T≤30,
2≤n≤1000,
0≤k≤1000
输入样例:
5
27 2
45 7
2 0
15 1
17 1
输出样例:
YES
NO
YES
YES
YES
呐!这里就用到了一个数学知识!
1 1 1~ n n n之间的质数的个数 1 ln n \frac{1}{\ln n} lnn1个,由于这一题的测试数据很小,可以和直接暴力枚举,1000以内的质数大概一两百个,如果这个时候遍历的话,那么就是几万的复杂度
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int N=1010;
int primes[N],cnt;
bool st[N];
void get_prime(int n)//线性筛质数即欧拉筛
{
for(int i=2;i<=n;i++)
{
if(!st[i])primes[cnt++]=i;
for(int j=0;primes[j]<=n/i;j++)
{
st[primes[j]*i]=true;
if(i%primes[j]==0)
break;
}
}
}
int main()
{
get_prime(N-1);
int T;
cin>>T;
while(T--)
{
int n,k;
cin>>n>>k;
int res=0;
for(int i=2;i<=n;i++)
{
if(st[i])continue;
for(int j=1;j<cnt;j++)
if(primes[j-1]+primes[j]+1==i)
{
res++;
break;
}else if(primes[j-1]+primes[j]+1>i)
break;
}
if(res>=k)
puts("YES");
else puts("NO");
}
return 0;
}
五、3794. 构造字符串(思维题)
给定一个整数 n,请你构造一个长度为 n 的字符串,要求:
字符串中不含 a,b,c 以外的字符。
字符串中不含长度为 3 的回文子串。
字符串中 c 的数量尽可能少(最好没有)。
输入格式
一个整数 n。
输出格式
一个满足条件的字符串。
如果答案不唯一,则输出任意合理方案均可。
数据范围
1≤n≤2×105。
输入样例1:
2
输出样例1:
aa
输入样例2:
3
输出样例2:
bba
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
if(i%4<2)cout<<'a';
else cout<<'b';
return 0;
}