Round350div2简易题解(cf)

这是我做过的最sb的一场div2,没AK有点可惜,F有些小trick
670A holidays
根据%7的结果判一下就好了

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<stack>
#include<string>
#define MAX 200000
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
int dp[MAX+10];
int num[MAX+10];
int main(void)
{
    int n,t;
        scanf("%d",&n);
        int mx=(int)(n/7)*2;
        mx+=min(n%7,2);
        int mn=(int)(n/7)*2;
        mn+=max(0,n%7-5);
    printf("%d %d\n",mn,mx);
    return 0;
}

670BGame of Robots
搞清楚是第几个人在报数和报到第几个数就好了,是一个等差数列前n项和,然后xjbg

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<stack>
#include<string>
#define MAX 200000
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
LL nn[MAX+10];
LL num[MAX+10];
int siz=0;
void init(){
    num[1]=1;
    for(int i=2;i<=100010;i++){
        num[i]=num[i-1]+(LL)i;
        if(num[i]>2000000100LL)break;
        siz=i;
    }
}
int main(void)
{
    init();
    LL n,k;
    scanf("%I64d %I64d",&n,&k);
    for(int i=1;i<=n;i++){
        scanf("%I64d",&nn[i]);
    }
    LL ans=0;
    int pp=lower_bound(num+1,num+1+siz,k)-num;
    if(num[pp]==k){
        ans=nn[pp];
    }
    else ans=nn[k- num[pp-1]];
    printf("%I64d\n",ans);
    return 0;
}

670C-Cinema
map搞一下,然后统计下就好了,用unordered_map不调参会被卡,数组别开小了

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<algorithm>
#include<stack>
#include<string>
#define Max 600000
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
map<int,int>mp;
int a[Max+10];
int b[Max+10];
int c[Max+10];
int vis1[Max+10];
int siz=0;
void add(int p){
    if(!mp.count(p))mp[p]=++siz;
}
int main(void)
{
    int n,m;
    scanf("%d",&n);
        memset(vis1,0,sizeof(vis1));
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        add(a[i]);
        vis1[mp[a[i]]]++;
    }
    scanf("%d",&m);
    for(int i=1;i<=m;i++){
        scanf("%d",&b[i]);
        add(b[i]);
    }
    for(int i=1;i<=m;i++){
        scanf("%d",&c[i]);
        add(c[i]);
    }
    int mn1,mn2;
    int flag=1;
    mn1=mn2=-1;
    for(int i=1;i<=m;i++){
        if(vis1[mp[b[i]]]>mn1){
            mn1=vis1[mp[b[i]]];
            mn2=vis1[mp[c[i]]];
            flag=i;
        }
        else if(vis1[mp[b[i]]]==mn1){
            if(vis1[mp[c[i]]]>mn2){
                mn2=vis1[mp[c[i]]];
                flag=i;
            }
        }
    }
    printf("%d\n",flag);
    return 0;
}

670D1,D2-Magic Powder - 2
二分答案,判是否可行

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<stack>
#include<string>
#define MAX 200000
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
LL a[MAX];
LL b[MAX];
int main(void)
{
    LL n,k;
    scanf("%I64d%I64d",&n,&k);LL ans=0;
    for(int i=1;i<=n;i++)scanf("%I64d",&a[i]);
    for(int i=1;i<=n;i++)scanf("%I64d",&b[i]);
    LL l=0;
    LL r=2000000010;
    while(l<=r){
        LL mid=((l+r)>>1);
        LL sum=0;
        int flag=1;
        for(int j=1;j<=n;j++){
            if(a[j]*mid>b[j]){
                sum+=(a[j]*mid-b[j]);
                if(sum>k){
                    r=mid-1;
                    flag=0;
                    break;
                }
            }
        }
        if(!flag)continue;
        ans=max(mid,ans);
        l=mid+1;
    }
    printf("%I64d\n",ans);
    return 0;
}

670E-Correct Bracket Sequence Editor
先匹配一下括号,光标移动和删除用链表模拟就好了

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<stack>
#include<string>
#define MAX 200000
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
char str[500050];
int st[500050];
int pp[500050];
char op[500050];
int fst=0;
struct node{
    int l,r;
}lst[500050];
int main(void)
{
    int n,m,p;
    scanf("%d%d%d",&n,&m,&p);
    scanf("%s",str+1);
    for(int i=1;i<=n;i++){
        if(str[i]=='(')st[++fst]=i;
        else {
            pp[i]=st[fst--];
            pp[pp[i]]=i;
        }
    }
    for(int i=0;i<=n;i++){
        lst[i].l=i-1;
        lst[i].r=i+1;
    }
    scanf("%s",op+1);
    for(int i=1;i<=m;i++){
        if(op[i]=='R')p=lst[p].r;
        else if(op[i]=='L')p=lst[p].l;
        else {
            if(p>pp[p])p=pp[p];
            int ll=lst[p].l;
            int rr=lst[pp[p]].r;
            lst[ll].r=rr;
            lst[rr].l=ll;
            p=rr;
            if(p==n+1)p=ll;
        }
    }
    for(int i=lst[0].r;i!=n+1;i=lst[i].r){
        printf("%c",str[i]);
    }
    puts("");
    return 0;
}

670F-Restore a Number
有点烦的一道模拟
先通过观察原串的长度的范围可以确定原串的长度,然后去掉不相干的数字,然后从小向大输出。
前导零我判的比较麻烦,我是首先找到一个除了字串以外最小不为0的数,然后判断这个和字串的大小。
1.如果大于子串首字母,就先放子串
2.如果小于子串首字母,就先放这个字符。
3.如果等于子串首字母,判一下子串比不比这个字符为首所能形成的最小的长度相等的串小,如果小就放子串,如果不小就先放这个字符
然后确定了首位,到后面就好判了,观察这个子串是不是小于全为子串首位的,比如1001<1111,如果小于就先放子串再放这一种字母,如果大于就先放这个字母再放子串,注意从头到尾子串放一次就够了
最后注意原串为零的情况以及除去子串以外全为零的情况

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<stack>
#include<string>
#define Max 1000010
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
char str[Max];
char str2[Max];
int num[15];
int main(void)
{
    scanf("%s",str+1);
    scanf("%s",str2+1);
    int len,len2;
    int rl;
    len=strlen(str+1);
    len2=strlen(str2+1);
    if(len-1<=9)rl=len-1;
    else if(len-2<=99)rl=len-2;
    else if(len-3<=999)rl=len-3;
    else if(len-4<=9999)rl=len-4;
    else if(len-5<=99999)rl=len-5;
    else if(len-6<=999999)rl=len-6;
    memset(num,0,sizeof(num));
    for(int i=1;i<=len;i++){
        num[str[i]-'0']++;
    }
    while(rl){
        int bit=rl%10;
        num[bit]--;
        rl/=10;
    }
    for(int i=1;i<=len2;i++){
        num[str2[i]-'0']--;
    }
    int flag2=0;
    for(int i=2;i<=len2;i++){
        if(str2[i]<str2[i-1]){
            flag2=1;
            break;
        }
        else if(str2[i]>str2[i-1]){
            flag2=0;
            break;
        }
    }
    int flag=1;int ff=0;
    for(int i=1;i<=9;i++){
        if(num[i]!=0){
            ff=1;
            if(str2[1]!='0'){
                if(str2[1]-'0'<i){
                    printf("%s",str2+1);
                    flag=0;
                }
                else if(str2[1]-'0'==i){
                    if(flag2){
                        int flag3=-1;
                        int st=2;
                        num[i]--;
                        for(int j=0;j<=9;j++){
                            for(int k=1;k<=num[j];k++){
                                if(str2[st]-'0'<j){flag3=1;break;}
                                else if(str2[st]-'0'>j){flag3=0;break;}
                                st++;
                                if(st>len2)break;
                            }
                            if(st>len2||flag3!=-1)break;
                        }
                        num[i]++;
                        if(flag3){
                            printf("%s",str2+1);
                            flag=0;
                        }
                        else {
                            printf("%d",i);
                            num[i]--;
                        }
                    }
                    else {
                        printf("%d",i);
                        num[i]--;
                    }
                }
                else {
                    printf("%d",i);
                    num[i]--;
                }
            }
            else {
                printf("%d",i);
                num[i]--;
            }
            for(int j=0;j<=9;j++){
                if(flag&&flag2){
                    if(j>=(str2[1]-'0')){
                        printf("%s",str2+1);
                        flag=0;
                    }
                }
                for(int k=1;k<=num[j];k++){
                    printf("%d",j);
                }
                if(flag&&(!flag2)){
                    if(j>=(str2[1]-'0')){
                        printf("%s",str2+1);
                        flag=0;
                    }
                }
            }
            break;
        }
    }if(!ff){
        printf("%s",str2+1);
        for(int i=1;i<=num[0];i++){
            printf("0");
        }
        puts("");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值