2021暑假每日一题(5)

一、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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值