Codeforces Round #555 Div. 3

题目链接:戳我

完了,最菜就是我了。div.3都写不动QAQ

A

按照题意模拟即可,注意判重

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#define MAXN 100010
using namespace std;
int n;
vector<int>v;
map<int,int>m;
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d",&n);
    while(n)
    {
        if(m.count(n)==0)v.push_back(n);
        else break;
        m[n]=1;
        n+=1;
        while(n%10==0) n/=10;
    }
    printf("%d\n",v.size());
    return 0;
}

B

开始看错题了嘤嘤嘤,注意是连续的一段
直接贪心就行了吧

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#define MAXN 300010
using namespace std;
int n,kkk;
int a[MAXN],to[MAXN];
bool flag=false;
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%1d",&a[i]);
    for(int i=1;i<=9;i++) scanf("%d",&to[i]);
    for(int i=1;i<=n;i++)
    {
        if(to[a[i]]>a[i]&&flag==false)
        {
            kkk=a[i];
            a[i]=to[a[i]];
            flag=true;
            for(int j=i+1;j<=n;j++)
            {
                if(to[a[j]]>=a[j]) a[j]=to[a[j]];
                else break;
            }
            break;
        }
    }
    for(int i=1;i<=n;i++) printf("%d",a[i]);
    return 0;
}

C1

因为数都不一样,所以枚举数就行了,看看每次要拿走哪边的qwq

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#define MAXN 300010
using namespace std;
int n,kkk,maxx=-0x3f3f3f3f,ans;
int a[MAXN],to[MAXN];
bool flag=false;
vector<char>vec;
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    int l=1,r=n;
    for(int i=1;i<=n;i++)
    {
        if(a[l]==i) vec.push_back('L'),l++,ans++;
        else if(a[r]==i) vec.push_back('R'),r--,ans++;
    }
    cout<<ans<<endl;
    for(int i=0;i<vec.size();i++) cout<<vec[i];
    cout<<endl;
    return 0;
}

C2

和上一个题唯一不一样的就是这里的值可能不相等。
注意当两边相等的时候,需要求一下两边各能延展多远,找能取数最多的一边取qwq

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#define MAXN 300010
using namespace std;
int n,kkk,maxx=1,ans;
int a[MAXN],to[MAXN];
bool flag=false;
vector<char>vec;
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    int l=1,r=n;
    while(maxx<=200000)
    {
        if(l>r||(a[l]<maxx&&a[r]<maxx)) break;
        if(l==r&&a[l]==maxx)
        {
            if(a[l]==maxx) vec.push_back('L'),l++,ans++;
            else break;
        }
        else if(a[l]==maxx&&a[r]==maxx)
        {
            int cnt1=0,cnt2=0;
            for(int j=l+1;j<=r;j++)
            {
                if(a[j]>a[j-1]) cnt1++;
                else break;
            }
            for(int j=r-1;j>=l;j--)
            {
                if(a[j]>a[j+1]) cnt2++;
                else break;
            }
            if(cnt1>cnt2)
            {
                maxx=a[l+cnt1]+1;
                for(int j=0;j<=cnt1;j++)
                    vec.push_back('L'),l++,ans++;

            }
            else
            {
                maxx=a[r-cnt2]+1;
                for(int j=0;j<=cnt2;j++)
                    vec.push_back('R'),r--,ans++;

            }
            continue;
        }
        else if(a[l]==maxx) vec.push_back('L'),l++,ans++;
        else if(a[r]==maxx) vec.push_back('R'),r--,ans++;
        maxx++;
    }
    printf("%d\n",ans);
    for(int i=0;i<vec.size();i++) printf("%c",vec[i]);
    return 0;
}

D

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 200010
using namespace std;
int n,k,nn;
int a[MAXN];
inline bool check()
{
    long long cur_ans=a[1];
    for(int i=2;i<=k;i++)
    {
        if(a[i]<=a[i-1]) {return false;}
        if(a[i]>a[i]*2) {return false;}
        cur_ans+=a[i];
    }
    if(cur_ans!=1ll*nn) return false;
    return true;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d%d",&n,&k);
    nn=n;
    for(int i=1;i<=k;i++)
    {
        a[i]=max(a[i-1]+1,(int)ceil((double)n/(pow(2.0,k-i+1)-1)));
        n-=a[i];
    }
    if(check()==false) printf("NO\n");
    else
    {
        printf("YES\n");
        for(int i=1;i<=k;i++) printf("%d ",a[i]);
    }
    return 0;
}

E

给你两个序列,要求对B进行重排,使得之后\((A[i]+B[i])\mod n\)生成的C序列字典序最小。
直接贪心地找B序列中有没有\(n-A[i]\)的数,或者离这个数最近的数就行了嘛。
上一个multiset+lower_bound即可,如果迭代器到了最末尾,让它返回.begin()
不过需要注意一点.....set的lower_bound需要这样写

multiset<int>::iterator it=s.lower_bound(k);

而不是

multiset<int>::iterator it=lower_bound(s.begin(),s.end(),k);

第二种写法会T......谁知道到底是为什么qwq

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#define MAXN 200010
using namespace std;
int n;
int a[MAXN],b[MAXN],c[MAXN];
multiset<int>s;
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int i=1;i<=n;i++) scanf("%d",&b[i]),s.insert(b[i]);
    // for(multiset<int>::iterator it=s.begin();it!=s.end();it++) cout<<(*it)<<" "; cout<<endl;
    for(int i=1;i<=n;i++)
    {
        // printf("i=%d\n",i);
        multiset<int>::iterator cur=s.lower_bound(n-a[i]);
        if(cur==s.end()) cur=s.begin();
        // cout<<(*cur1)<<" "<<(*cur2)<<endl;
        c[i]=((*cur)+a[i])%n;
        s.erase(cur);
    }
    for(int i=1;i<=n;i++) printf("%d ",c[i]);
    return 0;
}

F

G

不太会,先咕着。

原文地址:https://www.cnblogs.com/fengxunling/p/10778950.html

时间: 2024-10-25 03:46:07

Codeforces Round #555 Div. 3的相关文章

Codeforces Round # 555 (Div. 3) C2. Increasing subsequence (complicated version) (贪心)

题目链接:http://codeforces.com/contest/1157/problem/C2 当左右两边数字相同时,需要判断一下取哪边能得到更长的递增序列 #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <cstdio> #include <queue> #include <climits>

Codeforces Round #555 (Div. 3)[1157]题解

不得不说这场div3是真的出的好,算得上是从我开始打开始最有趣的一场div3.因为自己的号全都蓝了,然后就把不经常打比赛的dreagonm的号借来打这场,然后...比赛结束rank11(帮dreagonm上蓝果然没有食言qwq). (震惊...HA省A队CF青名...) CF1157A Reachable Numbers 水题,分析一下不难发现不超过\(10\)次就会少一位,然后\(10^9\)范围内的数可以到达的数个数显然不多,不妨大力模拟,然后把出现的数扔进set,最后输出set.size(

Codeforces Round #555 (Div. 3) A B C1(很水的题目)

A. Reachable Numbers 题意:设f(x)为 x+1 这个数去掉后缀0的数,现在给出n,问经过无数次这种变换后,最多能得到多少个不同的数. 代码 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<queue> #include<stack> #include<set> #include<

E Minimum Array ( Codeforces Round #555 (Div. 3) )

You are given two arrays aa and bb, both of length nn. All elements of both arrays are from 00 to n−1n−1. You can reorder elements of the array bb (if you want, you may leave the order of elements as it is). After that, let array cc be the array of l

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i

Codeforces Round #424 (Div. 2) D. Office Keys(dp)

题目链接:Codeforces Round #424 (Div. 2) D. Office Keys 题意: 在一条轴上有n个人,和m个钥匙,门在s位置. 现在每个人走单位距离需要单位时间. 每个钥匙只能被一个人拿. 求全部的人拿到钥匙并且走到门的最短时间. 题解: 显然没有交叉的情况,因为如果交叉的话可能不是最优解. 然后考虑dp[i][j]表示第i个人拿了第j把钥匙,然后 dp[i][j]=max(val(i,j),min(dp[i-1][i-1~j]))   val(i,j)表示第i个人拿

Codeforces Round #424 (Div. 2) C. Jury Marks(乱搞)

题目链接:Codeforces Round #424 (Div. 2) C. Jury Marks 题意: 给你一个有n个数序列,现在让你确定一个x,使得x通过挨着加这个序列的每一个数能出现所有给出的k个数. 问合法的x有多少个.题目保证这k个数完全不同. 题解: 显然,要将这n个数求一下前缀和,并且排一下序,这样,能出现的数就可以表示为x+a,x+b,x+c了. 这里 x+a,x+b,x+c是递增的.这里我把这个序列叫做A序列 然后对于给出的k个数,我们也排一下序,这里我把它叫做B序列,如果我

[Codeforces] Round #352 (Div. 2)

人生不止眼前的狗血,还有远方的狗带 A题B题一如既往的丝帛题 A题题意:询问按照12345678910111213...的顺序排列下去第n(n<=10^3)个数是多少 题解:打表,输出 1 #include<bits/stdc++.h> 2 using namespace std; 3 int dig[10],A[1005]; 4 int main(){ 5 int aa=0; 6 for(int i=1;;i++){ 7 int x=i,dd=0; 8 while(x)dig[++dd

Codeforces Round #273 (Div. 2)

Codeforces Round #273 (Div. 2) 题目链接 A:签到,仅仅要推断总和是不是5的倍数就可以,注意推断0的情况 B:最大值的情况是每一个集合先放1个,剩下都丢到一个集合去,最小值是尽量平均去分 C:假如3种球从小到大是a, b, c,那么假设(a + b) 2 <= c这个比較明显答案就是a + b了.由于c肯定要剩余了,假设(a + b)2 > c的话,就肯定能构造出最优的(a + b + c) / 3,由于肯定能够先拿a和b去消除c,而且控制a和b成2倍关系或者消除