Codeforces Round 900 (Div. 3)

目录

A. How Much Does Daytona Cost?

B. Aleksa and Stack 

C. Vasilije in Cacak 

D. Reverse Madness 


 





A. How Much Does Daytona Cost?

输入样例:

7
5 4
1 4 3 4 1
4 1
2 3 4 4
5 6
43 5 60 4 2
2 5
1 5
4 1
5 3 3 1
1 3
3
5 3
3 4 1 5 5

输出样例:

YES
NO
NO
YES
YES
YES
YES

思路: 签到题,直接看数组中有没有出现这个数就行了

代码:

#include<iostream>
#include<map>
using namespace std;
int main()
{
    int t;cin>>t;
    while(t--)
    {
        map<int,int> h;
        int n,k;cin>>n>>k;
        for(int i=0;i<n;i++)
        {
            int x;cin>>x;
            h[x]++;
        }
        if(h[k]) puts("YES");
        else puts("NO");
    }
}

B. Aleksa and Stack 

输入样例:
 

3
3
6
7

输出样例:

6 8 12
7 11 14 20 22 100
9 15 18 27 36 90 120

思路: 当时做的时候就想到了直接用1 3 5 7 9.....输出,毕竟是B题不能想复杂了哈哈( ̄▽ ̄)"

代码:

#include<iostream>
#include<map>
using namespace std;
int main()
{
    int t;cin>>t;
    while(t--)
    {
        int n;cin>>n;
        int m=1;
       while(n--) 
       {
        cout<<m<<' ';
        m+=2;
       }
            puts("");
    }
}

C. Vasilije in Cacak 

输入样例:

12
5 3 10
5 3 3
10 10 55
6 5 20
2 1 26
187856 87856 2609202300
200000 190000 19000000000
28 5 2004
2 2 2006
9 6 40
47202 32455 613407217
185977 145541 15770805980

输出样例:

YES
NO
YES
YES
NO
NO
YES
NO
NO
NO
YES
YES

思路:这道题可以先等差数列求和将1~n的和算出来S(n),接下来可以分情况讨论

           第一种:如果k>n肯定是不行的,输出NO

           第二种:如果S(n)<x,说明无论你怎么取都不可能达到x,输出NO

           第三种:如果S(n)==x,说明只有取走所有数才会成立,即k==n输出YES,反之NO

           第四种:如果S(n)>x,那么我们该如何判断一定就能取k个数呢,我们会发现将1~k求和是取k个数的最小值Min(n),而n-k+1 ~ n求和是取k个数的最大值Max(n),所以x只需要满足Min(n)<=x<=Max(n)就可以了。

注意题目给的数据范围,要开longlong

代码:

#include<iostream>
#include<map>
#define int long long
using namespace std;
int32_t main()
{
  
    int t;cin>>t;
    while(t--)
    {
        int n,k,x;cin>>n>>k>>x;
        int sum=n*(n+1)/2;
        if(k>n)
        {
            puts("NO");
            continue;
        }
        if(sum<x) puts("NO");
        else if(sum==x)
        {
          if(k<n) puts("NO");
          else puts("YES");            
        }
        else
        {
         
            int sum1=k*(k+1)/2;
            int sum2=sum1;
            sum1=k*(n+n-k+1)/2;
            int sum3=sum1;
            if(sum3>=x&&x>=sum2) puts("YES");
            else puts("NO");

        }
    }
}

D. Reverse Madness 

         

输入样例:

5
4 2
abcd
1 3
2 4
2
1 3
5 3
abcde
1 2 3
1 2 5
3
1 2 3
3 1
gaf
1
3
2
2 2
10 1
aghcdegdij
1
10
5
1 2 3 4 2
1 1
a
1
1
1
1

输出样例:

badc
abedc
gaf
jihgedcdga
a

思路: 一开始只用了二分,每次查一个区间就reversse一次,没想到TLE了(/(ㄒoㄒ)/~~,事实证明我就是蒟蒻🤣),然后改了一个多小时,改不动了直接看大佬的代码,发现要用差分和前缀和做,而且我们还可以发现区间[a,b]在[Li,Ri]中是对称存在的,比如Li=1,Ri=4,x=2,那么a=2,b=3(当时做题的时候怎么就没想到呢😱),接下来就是计算每个位置要翻转的次数,如果是奇数次则与对称得位置翻转,详情请看代码。

代码:

#include<iostream>
#include<map>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int N=2e5+5;
typedef pair<int,int> PII;
int d[N];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    int t;cin>>t;
    while(t--)
    {
       int n,k;cin>>n>>k;
       string s;cin>>s;
       PII tr[k+5];
       memset(d,0,sizeof d);
       vector<int> b(n+5);
       for(int i=1;i<=k;i++)
        cin>>tr[i].first;;
       for(int i=1;i<=k;i++) {cin>>tr[i].second; b[i]=tr[i].second;}
       int q;cin>>q;
       while(q--)
       {
        int x;cin>>x;
        int pos=lower_bound(b.begin()+1,b.begin()+k+1,x)-b.begin();
     //   cout<<tr[L].first<<' '<<tr[L].second<<endl;
           //cout<<x<<' '<<tr[L].first+tr[L].second-x<<endl;
            int left=min(x,tr[pos].first+tr[pos].second-x);
            int right=max(x,tr[pos].first+tr[pos].second-x);
            d[left]++,d[right+1]--;
        
       }
       for(int i=1;i<=n;i++) d[i]+=d[i-1];
       for(int i=1;i<=k;i++)
       {
           int l=tr[i].first,r=tr[i].second;
           for(int j=l;j<=(l+r)/2;j++)
           {
               if(d[j]%2)
               {
                   swap(s[j-1],s[r-(j-l)-1]);
              
               }
           }
       }
       cout<<s<<endl;
    }
}

先写到这吧,剩下的过几天再补🤭。。(~ ̄▽ ̄)~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SuperRandi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值