Codeforces Round #755 Div. 2 ABCD

本文介绍了四道编程题目,分别是数学加法问题,通过化简方程求解;矩形染色的贪心策略,寻找最优染色方案;数组操作判断是否能通过+1操作转换成目标数组;以及交互式题目序列猜测,利用二分查找确定特定序列。每道题目都提供了AC代码和解题思路。
摘要由CSDN通过智能技术生成

A. Mathematical Addition
B. Coloring Rectangles
C. Two Arrays
D. Guess the Permutation

A. Mathematical Addition

请添加图片描述

思路分析
题目意思就是一个一个等价方程,给出 u 和 v,构造 x 和 y 使得方程成立
我的想法是化简一下方程,最后得到的结果是 x * v * v + y * u * u = 0,又知道 u 和 v,所以就能构造出来了

注意数据范围开 long long(因此WA了一发。。。)
AC代码

#include <iostream>
 
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
 
int t;
ll u, v;
ll x, y;
 
int main() {
    cin >> t;
    while (t--) {
        cin >> u >> v;
        x = - (u * u);
        y = v * v;
        cout << x << ' ' << y << endl;
    }
    return 0;
}

B. Coloring Rectangles

请添加图片描述

思路分析
分析完后就是贪心问题,将给定矩阵 贪心为 1 * 3 和 1 * 2,并且 1 * 3 要尽可能多一些

AC代码

#include <iostream>
 
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
 
const int N = 3 * 1e4 + 10;
 
int t;
int n, m;
 
int greedy(int x, int y) {
    int res = 0;
    res += (x / 3) * y;
    x = x % 3;
    res += (y / 3) * x;
    y = y % 3;
    if(x == 0 || y == 0)
        return res;
    if((x == 1 && y == 1) || (x == 1 && y == 2) || (x == 2 && y == 1))
        return res+1;
    if(x == 2 && y == 2)
        return res + 2;
}
 
int main() {
    cin >> t;
    while (t--) {
        cin >> n >> m;
        cout << greedy(n, m) << endl;
    }
    return 0;
}

C. Two Arrays

请添加图片描述

思路分析
题读明白了就不难,让数组a通过一些操作变为数组b,因为题目限制了只能+1,且顺序不一样。
因此对数组a和数组b排序后,对应下标的值要么相等,要么 a[i] + 1 == b[i],如果均符合,输出YES,否则输出NO

AC代码

#include <iostream>
#include <algorithm>
 
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
 
const int N = 110;
 
int t;
int n;
int a[N], b[N];
 
int main() {
    cin >> t;
    while (t--) {
        cin >> n;
        for(int i = 0; i < n; i++)
            cin >> a[i];
        for(int i = 0; i < n; i++)
            cin >> b[i];
        sort(a,a + n);
        sort(b, b + n);
        bool flag = true;
        for(int i = 0;i < n; i++)
            if(b[i] == a[i] || b[i] == a[i] + 1)
                flag = true;
            else {
                flag = false;
                break;
            }
        if(flag)
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }
    return 0;
}

D. Guess the Permutation

请添加图片描述
思路分析
交互题,第一次做
因为 1e9 内要二分 n 需要至多 30 次,所以只有在剩下的几次中发现答案
先二分出 i 或者 k,这两个点的性质肯定是逆序数总和刚好改变的点
所以需要先求逆序数的总和,就可以确定 i 和 k 中的一个点
后面最大的数贡献的逆序数刚好是它本身减1,这样就可以在两步确定一段区间的长度了

AC代码

#include <iostream>
#include <algorithm>
 
using namespace std;
typedef pair<int, int> PII;
typedef long long ll;
 
const int N = 110;
 
int t;
int n;
 
int ask(int l, int r) {
    string s;
    cout << "? " << l << " " << r << endl;
    cin >> s;
    int res = 0;
    for (int i = 0; i < s.size(); i++) {
        res *= 10;
        res += s[i] - '0';
    }
    return res;
}
 
int main() {
    cin >> t;
    while (t--) {
        cin >> n;
        int l = 2, r = n - 3;
        int m = ask(1, n);
        while (l <= r) {
            int mid = l + r >> 1;
            if (ask(mid, n) == m) {
                l = mid + 1;
            } else
                r = mid - 1;
        }
        int i = r;
        int j = i + m - ask(r + 1, n) + 1;
        int k = j + ask(j, n) - ask(j + 1, n);
        cout << "! " << i << " " << j << " " << k << endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值