Codeforces Round #624 (Div. 3)

比赛链接

A题 解题思路:


简单的数学思维题:
1. 如果相同 a , b 相同,那么输出 0
2. 如果 b > a ,如果相差偶数,那么我们加 2次奇数即可,如果相差奇数,那么我们直接加一次奇数。
3. 如果 a > b,那么相反。


代码:


#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>

using namespace std;

int main(){
    int t;
    cin>>t;
    while(t--){
        int a ,b;
        cin>>a>>b;
        if (a == b) {
            cout<<0<<endl;
        }
        else if (a < b){
            if ((b - a) % 2 == 0 ){
                cout<<2<<endl;
            }
            else{
                cout<<1<<endl;
            }
        }
        else{
            if ((a - b) % 2 == 1){
                cout<<2<<endl;
            }
            else{
                cout<<1<<endl;
            }
        }
    }
    return 0;

}

B题 解题思路:


看似冒泡排序,就是求能否实现从小到大排序,时间复杂度n ^ 2 。

当前输入的值,如果前面有比当前值大的值时,我们就要进行位置转换,所以,在第一个比当前位置大的值开始,到当前值的前一个,都必须符合转换条件,因此我们将值设为 1 (另外开个数组存储),然后我们对输入的可以进行位置转换的位置将值设置为0 ,最终我们判断 1 — n 的值是否全为 0 即可。


代码:


#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>

using namespace std;

int ans[1000];
int res[1000];
int fun[1000];

int main(){
    int t;
    cin>>t;
    while(t--){
        memset(fun,0,sizeof fun);
        int n , m;
        int k = 0;
        cin>>n>>m;
        for (int i = 1; i <= n; i++){
            cin>>ans[i];
            int x = 0;
            for (int j = 1; j < i;j++ ){ // 寻找前面是否存在更大值
                if (ans[i] < ans[j]){
                    fun[j] = 1;
                    x = j;
                    break;
                }
            }
            if (x != 0){ // 如果存在,那么将这一路的数值赋值为 1
                for (int j = x + 1; j < i; j++){
                    fun[j] = 1;
                }
            }
        }
        for (int i = 1; i <= m; i ++){  // 都赋值为 0
            int l;
            cin>>l;
            fun[l] = 0;
        }
        int p = 0;
        for (int i = 1; i <= n; i++){
            if (fun[i] == 1){
                p = 1;
                break;
            }
        }
        if (p) puts("NO");
        else puts("Yes");

    }
    return 0;

}


C题 解题思路:


给予字符串,然后给予一些间断点,在这个间断点时,会停止,最终分成一些子串,求每种字符出现的个数。
我们求出每次间断点之前,字符出现的个数,然后我们后面就直接求两个间断点直接的字符即可(之前的我们都保存,直接相加即可),然后最终输出。


代码:


#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>

using namespace std;

const int N = 200010;

int ans[N];
int res[N];
int fun[N];

int main(){
    int t;
    cin>>t;
    while(t--){
        memset(res,0,sizeof res);
        memset(fun,0,sizeof fun);
        int n, m;
        string st;
        scanf("%d%d",&n,&m);
        cin>>st;
        for (int i = 1; i <= m; i ++){
            scanf("%d",&ans[i]);
//            for (int j = 0; j < ans[i]; j++){
//                res[st[j] - 'a'] ++;
//            }
        }
        sort(ans + 1 , ans + 1 + m);
        for (int i = 1; i <= m; i++){
            for (int j = 0; j < 26; j ++){
                if (res[j] != 0){
                    res[j] += fun[j];
                }
            }
            for (int j = ans[i - 1]  ; j <= ans[i] - 1; j ++){
                fun[st[j] - 'a'] ++;
                res[st[j] - 'a'] ++;
            }
        }

        for (int i = 0; i < n; i ++){
            res[st[i] - 'a'] ++;
        }
        for (int i = 0; i < 26; i++){
            printf("%d ",res[i]);
        }
        printf("\n");
    }
    return 0;

}


D题 解题思路:


暴力出奇迹!(这种题其实暴力解法,时间复杂度往往是最低的)

n ^ 3 , 里面有些情况直接跳出。

首先我们枚举 a, 枚举到 n, 然后我们 枚举 b = a,然后 b += a, 因为保证倍数,同样道理枚举 c , 然后如果存在,那么我们求出最小值即可。


代码:


#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

int n = 100010;

int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        int a, b, c;
        int mx = 1e9;
        scanf("%d%d%d", &a, &b, &c);
        int x = 0, y = 0, z = 0;
        for (int i = 1; i <= n; i ++){
            for (int j =  i; j <= n; j += i){
                for (int k = j; k <= n; k += j){
                    int res = abs(i - a) + abs(b - j) + abs(c - k);
                    if (mx > res){
                        mx = res;
                        x = i, y = j, z = k;
                    }
                }

            }
        }
        cout<<mx<<endl;
        printf("%d %d %d\n",x, y, z);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值