牛客周赛67

https://ac.nowcoder.com/acm/contest/95016#question)(比赛链接)

目录

A.排序危机

B.小歪商店故事:卷

C.小苯的计算式

D.K

E.小苯的区间选数


A.排序危机

1.思路

        遍历三次字符串,依次输出小写字母、数字、大写字母(输出数字的时候少了0卡了半天。。)

2.代码

#include <bits/stdc++.h>
#define int long long
using namespace std;

signed main(){
    int n;
    cin>>n;
    string s;
    cin>>s;
    string re = "";
    for(int i=0;i<n;i++){
        if(s[i]>='a'&&s[i]<='z'){
            re+=s[i];
        }
    }
    for(int i=0;i<n;i++){
        if((s[i]-'0')>=1&&(s[i]-'0')<=9){
            re+=s[i];
        }
    }
    for(int i=0;i<n;i++){
        if(s[i]>='A'&&s[i]<='Z'){
            re+=s[i];
        }
    }
    cout<<re<<endl;
    return 0;
}

B.小歪商店故事:卷

1.思路

        直接利用c*b/d算amax,再乘回去是否能等于c*b,能的话说明re正好等于amax,需要对re-1,否则算出来的re是已经去除小数部分的数值,就是amax,无需更改,输出a-re就行

2.代码

#include <bits/stdc++.h>
#define int long long 
using namespace std;

void solve(){
    int a,b,c,d;
    cin>>a>>b>>c>>d;
    int re = (c*b)/d;
    if((re*d)==(c*b)){
        re-=1;
    }
    cout<<a-re<<" ";
}

signed main(){
    int n;
    cin>>n;
    while(n--){
        solve();
    }
    cout<<endl;
}

C.小苯的计算式

1.思路

        暴力枚举即可,直接枚举从0到C的所有情况,前提是保证整个式子的长度和为n

2.代码

#include <bits/stdc++.h>
#define int long long
using namespace std;

signed main(){
    int n;
    string s;
    cin>>n>>s;
    int c = stoi(s);
    int len = s.length();
    int yu = n-2-len;
    int sum = 0;
    for(int i=0;i<=c;i++){
        int t = c-i;
        int len1 = to_string(i).length();
        int len2 = to_string(t).length();
        if(len1+len2==yu){
            sum+=1;
        }
    }
    cout<<sum<<endl;
    return 0;
}

D.K

1.思路

        极大不同区间的最大宽度为1,所以k的最大值只能是n,因此当k>n的时候一定构造不出来。这题观察示例1可以发现通过不断重复元素的方式来保证区间长度不变的情况下,不断增加极大不同区间的个数。如145,后重复1,既保证了区间长度为3,即451,又使得个数增加。451后重复4,保证区间长度为3,即514,又使得个数增加。多个例子探讨发现这种规律是可行的,但要如何构造初始区间呢。即145还有初始区间的个数,还是通过找规律发现,初始构造区间的个数为n-k+1,且初始区间递增也满足上述的要求,此后不断重复输出初始区间即可,直到输出n个数

    // 6 2
    // 1 2 3 4 5 1 
    // 6 3
    // 1 2 3 4 1 2
    // 6 4
    // 1 2 3 1 2 3
    // 6 5
    // 1 2 1 2 1 2

2.代码

#include <bits/stdc++.h>
#define int long long
using namespace std;

const int N = 2e5+7;
int a[N];

signed main(){
    int n,k;
    cin>>n>>k;
    if(k>n){
        cout<<"NO"<<endl;
        return 0;
    }
    cout<<"YES"<<endl;
    int t = n-k+1;
    for(int i=1;i<=t;i++){
        a[i] = i;
        cout<<i<<" ";
    }
    int yu = n-t;
    int index = 1;
    for(int i=1;i<=yu;i++){
        cout<<a[index]<<" ";
        index++;
        if(index==t+1){
            index=1;
        }
    }
    return 0;
}

    // 6 2
    // 1 2 3 4 5 1 
    // 6 3
    // 1 2 3 4 1 2
    // 6 4
    // 1 2 3 1 2 3
    // 6 5
    // 1 2 1 2 1 2

E.小苯的区间选数

1.思路

        题目中选取两个数求和可以转化为从区间 [l1+l2,r1+r2] 选取一个数使得数位和最大。如何使得数位和最大,就是尽量让9的个数多,比如2134,我们选择将2-1,然后使后面所有数变为9,即1999。首先设置结果为左右区间的数位和取较大值,接下来探讨两种情况。

        当左右区间的长度相同的时候,对两个区间的对应位置的数值进行比较,比如:1234和1267,r[i] > l[i] 的时候才选择将i-1,否则会使得右区间小于左区间,不符合要求。

        当左右区间长度不相同的时候,直接对右区间第一个数-1,然后后面所有变9即可。有一种情况就是右区间为999999,按如上操作反而导致数位和变小,所有这就是为什么我们刚开始初始化的时候,设置结果为左右区间的数位和取较大值

2.代码

#include <bits/stdc++.h>
#define int long long
using namespace std;

void solve(){
    int l1,r1,l2,r2;
    cin>>l1>>r1>>l2>>r2;
    string l = to_string(l1+l2);
    string r = to_string(r1+r2);
    int ans = 0,anx = 0;
    for(int i=0;i<r.length();i++){
        ans += r[i]-'0';
    }
    for(int i=0;i<l.length();i++){
        anx += l[i]-'0';
    }
    int re = max(ans, anx);
    // cout<<"left:"<<l<<" "<<"right:"<<r<<" "<<re<<endl;
    if(r.length()>l.length()){
        int t = (r[0]-'0'-1)+(9*(r.length()-1));
        re = max(re,t);
    }else{
        int i = 0;
        int sum = 0;
        for(i;i<r.length();i++){
            if(l[i]>=r[i]){
                sum += r[i]-'0';
            }else{
                break;
            }
        }
        sum += r[i]-'0'-1;
        sum += (r.length()-i-1)*9;
        re = max(re,sum);
    }
    cout<<re<<endl;
}

signed main(){
    int t;
    cin>>t;
    while(t--){
        solve();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值