Codeforces Round #653 (Div. 3) (A ~ E1)

链接
A. Required Remainder
在这里插入图片描述
题意 : t组数据,每组给出x,y,n 在1到n中找出最大的数满足模x等于y
思路 : 直接二分查找,假定 r e s = a x + y res=a*x+y ,那么 a a 就属于0到 n / x n/x ,直接二分这个倍数,找出最大解就可以了

LL x, y, n;
void solve () {
    x = read(), y = read(), n = read();
    LL L = 0, R = 1e9 + 1, res = 0;
    while(L <= R) {
        LL mid = L + R >> 1;
        LL tmp = x * mid + y;
        if(tmp <= n) {
            res = tmp;
            L = mid + 1;
        } else {
            R = mid - 1;
        }
    }
    printf("%lld\n", res);
}

B. Multiply by 2, divide by 6
在这里插入图片描述
题意; T组数据,每组给出一个数 n n ,对于这个数你可以进行若干次操作,使得这个数乘于 2 2 或者除于 6 6 (前提是可以整除),你想要获得1,求出最小的操作数,或者说不存在
思路:首先给出的 n n 是大于等于1的,所以如果可以转换成功的话,那么最后一步一定是这个数除于 6 6 之后变成1,而除于6就必须要求这个数本身含有因子3,乘于2只会改变质因子2的个数,除于6则是消除一个2,消除一个3,所以先统计下质因子除了2和3以外是否还有其他质因子,有的话直接输出 n o no ,如果只含2和3的话,还需要保证2的个数不超过3的个数,因为我们只能增加2,每次消除2同时需要消除3
所以当且仅当质因子只含2和3,且2的因子数不超过3的因子数才可以,答案为 r e s = n u m 3 + ( n u m 3 n u m 2 ) res=num3 + (num3 - num2)

void solve () {
    LL n = read(), num2 = 0, num3 = 0;
    while(n != 1 && n % 2 == 0) {
        n /= 2;
        ++ num2;
    }
    while(n != 1 && n % 3 == 0) {
        n /= 3;
        ++ num3;
    }
    if(n != 1) {
        puts("-1");
        return ;
    }
    if(num2 > num3) {
        puts("-1");
    } else {
        LL dis = num3 - num2;
        printf("%lld\n",  num3 + dis);
    }
}

C. Move Brackets
在这里插入图片描述
题意:给出一个括号序列(保证左括号数目等于右括号),然后每次操作可以将一个字符移动到序列开头或者序列结尾,求出移到合法所需的最小步数
思路:
先放结论: 就是不规范的括号对数
证明 首先对于一个合法的括号对(),之后在它的两边套一个新的变成(())也是合法的,所以我们对于这个题的移动策略完全可以处理为,不合法的左括号全放在最左边,右括号全放在最右边,合法的对数都消除掉,同时只需要统计不合法的左括号数目就可以了,因为我们把它放在最左边那就一定有一个括号可以跟他想匹配,(不一定是和最右边的那个),所以这个其实就是不合法的数目,用栈维护就可以了,不懂的话就自己画一画

void solve () {
    int n = read();
    scanf("%s", str + 1);
    stack<char>sta;
    int res = 0;
    for(int i = 1; i <= n; ++ i) {
        if(str[i] == '(') {
            sta.push(str[i]);
        } else {
            if(sta.empty()) {
                ++ res;
            } else {
                sta.pop();
            }
        }
    }
    printf("%d\n", res);
}

D. Zero Remainder Array
在这里插入图片描述
题意: 有一种超能力初始效果为0,每天这个效果会加一,每天可以选择是否使用,但只有一次机会,可以给任意一个数增加上这个效果使得这个数变大,他需要把所有的数都变成 k k 的整数倍(mod后为0),求问至少需要多少天
思路:
这个其实简单,读入的时候把所有的数mod k处理一下,等于0的不管,不等于0的都需要加上(k-剩余的数),如果全部的需要的数都不重复就直接取最大的,扫一遍就过了,如果有重复的数,那就是出现次数最多的数中最大的那个数为最后一天,假设这个数需要m,出现了sum次,共有n个数,那么答案就是 ( s u m 1 ) n + m (sum-1)*n+m

LL arr[maxn], res[maxn], n, k;
vector<LL> vec;
map<LL, LL> mp;
void solve () {
    vec.clear();
    mp.clear();
    cin >> n >> k;
    LL cnt = 0;
    for(int i = 1; i <= n; ++ i) {
        cin >> arr[i];
        LL tmp = k - (arr[i] % k);
        res[i] = tmp == k ? 0 : tmp;
        mp[res[i]] ++;
        if(res[i]) {
            cnt = max(cnt, mp[res[i]]);
        }
    }
    LL ans = 0;
    for(int i = 1; i <= n; ++ i) {
        if(mp[res[i]] == cnt) {
            ans = max(ans, res[i]);
        }
    }
    ans = max(0ll, ans + (cnt - 1) * k + 1);
    printf("%lld\n", ans);
}

E1. Reading Books (easy version)
在这里插入图片描述
题意: n本书,两个孩子,每本书有需要读的时间和两个孩子是否喜欢它 这三个属性,之后每个孩子都需要读k本自己喜欢的,但是他们在同一时间必须要读同一本书,求问最少多少时间可以让两者都读完要求的书
思路
这个其实很简单,读入的时候,开三个 v e c t o r vector ,一个储存两者都喜欢的,一个储存a喜欢的,一个储存b喜欢的,之后把a,b两个数组都从小到大排序,然后取以两者最少的个数来取出来合并当成同一个,放入大数组,然后 s o r t sort 大数组,取前k个之和就行了

vector<int> vec_L, vec_R, res;
int n, k, arr[maxn];
void solve () {
    cin >> n >> k;
    for(int i = 1; i <= n; ++ i) {
        cin >> arr[i];
        int a, b;
        cin >> a >> b;
        if(a && b) {
            res.emplace_back(arr[i]);
        } else if(a) {
            vec_L.emplace_back(arr[i]);
        } else if(b) {
            vec_R.emplace_back(arr[i]);
        }
    }
    sort(vec_L.begin(), vec_L.end());
    sort(vec_R.begin(), vec_R.end());
    auto szl = vec_L.size(), szr = vec_R.size();
    for(int i = 0; i < szl && i < szr; ++ i) {
        res.emplace_back(vec_L[i] + vec_R[i]);
    }
    sort(res.begin(), res.end());
    auto szres = res.size();
    if(szres < k) {
        cout << -1;
    } else {
        int sum = 0;
        for(int i = 0; i < k; ++ i) {
            sum += res[i];
        }
        cout << sum << endl;
    }
}

猜你喜欢

转载自blog.csdn.net/leoxe/article/details/107384652