7-6号CFdiv3

题目以及官方题解

A题

题目大意

求1-n中对x取模余y的最大数;

题解

B题

题目大意

判断一个正整数是否可以只通过*2或者整除6(当前数为6的倍数可执行)这两个操作得到1

题解

暴力模拟,或者判断他的质因子是否只有2和3并且3的个数大于2的个数;

标程

暴力模拟

//
// Created by Visors on 2020/7/6.
//

#include <iostream>
#include <cmath>

using namespace std;
int t;
long long n;

int main() {
    cin >> t;
    while (t--) {
        cin >> n;
        int step = 0;
        bool flag = false;
        while (step < 1000) {
            if (n == 1) {
                flag = true;
                break;
            } else if (n % 6 == 0) n /= 6;
            else n *= 2;
            step++;
        }
        if (flag) cout << step << endl;
        else cout << "-1" << endl;
    }
    return 0;
}

C题

题目大意

给出一个由左右括号组成的字符串,请通过两种操作使其成为一个完美匹配的括号串。求最小操作数。

操作a:将一个字符移到串头

操作b:将一个字符移到串尾

题解

求未匹配括号对数。可以用栈操作。

标程

#include<bits/stdc++.h>
using namespace std;
 
int main()
{
    int t;
    cin>>t;
    while (t--)
    {
        stack<char > sta;
        int n;
        cin>>n;
        string s;
        cin>>s;
        int cnt=0;
        for(int i =0 ;i<n;i++)
        {
            if(s[i]=='(')
                sta.push('(');
            else
            {
                if(sta.empty())
                    cnt++;
                else sta.pop();
            }
        }
        cout<<cnt<<endl;   
    }
    
}

D题

题目大意

给出一个整数数组,和一个整数k,请通过两种操作使得数组所有整数都能被k整除。

初始时x=0;

操作1:选定一个数,将它+x,然后x++;

操作2:x++;

另外,对于数组中每个数只能执行最多一次操作1.

题解

找出所有未被k整除的数,并计算k-a[i]%k,设为v;

所有的数加上(1~z)*k+v后即可得到题目要求的结果,z为任意一个v的出现次数。

求出z,然后求要加的最大值即可得到答案。

标程

 
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
 
using namespace std;
 
map<int, int> m;
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin >> t;
    int n, k;
    while (t--) {
        m.clear();
        cin >> n >> k;
        int MAX = 0;
        for (int i = 1, a, mod; i <= n; i++) {
            cin >> a;
            mod = (k - a % k) % k;
            if (mod) m[mod]++;
            if (m[mod] > MAX) MAX = m[mod];
        }
        vector<int> v;
        for (auto it:m) {
//            cout << it.first << " " << it.second << endl;
            if (it.second == MAX) v.push_back(it.first);
        }
//        for (auto it:v) cout << it << endl;
        if (MAX) cout << (MAX - 1LL) * k + *max_element(v.begin(), v.end()) + 1 << endl;
        else cout << 0 << endl;
    }
    return 0;
}

E1题

题目大意

给出n本书的读取时间,以及是否被A和B喜欢

A和B需要在n本书中选出一些书籍,一起阅读,他们都需要至少读到k本喜欢的书

求最小阅读时间

题解

对书籍按11 、10、 01分成3类。然后排序。

进行k次取书操作:

当10、01中的min数之和,小于11中min数时取出10,01中的最小数,否则取出11中最小数。

对取出所有数求和。

标程

#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e5;
int num1[maxn], num2[maxn], num3[maxn];
int main()
{
    int n, m;
    cin >> n >> m;
    int k1, k2, k3;
    k1 = k2 = k3 = 0;
    int cnt = 0;
    int ans = 0;
    for (int i = 0; i < n; i++)
    {
        int x, y, z;
        cin >> x >> y >> z;
        if (!y && !z)
            continue;
        else if (y && z)
        {
            num1[k1++] = x;
        }
        else if (y && !z)
        {
            num2[k2++] = x;
        }
        else if (!y && z)
        {
            num3[k3++] = x;
        }
    }
        sort(num1, num1 + k1);
        sort(num2, num2 + k2);
        sort(num3, num3 + k3);
        int t1, t2, t3;
        t1 = t2 = t3 = 0;
            while (((t2 < k2 && t3 < k3) || t1 < k1 )&& cnt <m)
            {
                if ((t1 < k1 && t2 < k2 && t3 < k3 && num2[t2] + num3[t3] >= num1[t1])|| ((t2 >= k2 || t3 >= k3) && t1 < k1))
                {
                    cnt++;
                    ans += num1[t1++];
                }
                else if ((t1 < k1 && t2 < k2 && t3 < k3 && num2[t2] + num3[t3] < num1[t1]) || (t2 < k2 && t3 < k3 && t1>=k1))
                {
                    ans += num2[t2++] + num3[t3++];
                    cnt++;
                }
                //cout << cnt << " " << ans << endl;
            }
    if (cnt < m)
        cout << -1 << endl;
    else
    {
        cout << ans << endl;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值