菜鸡CF记录(只做出4题)

CF div2 117场次

A题原题网址

大致题意

在坐标轴上给定两点 分别为 A(0, 0), B(x, y),定义一个函数 d(A, B) = |Xa - Xb| + |Ya - Yb| 问是否能找到一点 C 使得

d(A, C) = d(A, B) / 2  
d(B, C) = d(A, B) / 2
其中 Xc, Yc >= 0
AC代码
#include <iostream>
#include<algorithm>
using namespace std;
int main(){
    int t;
    int x, y;
    scanf("%d", &t);
    while(t--){
        scanf("%d%d", &x, &y);
        if(x == y) printf("0 %d\n", y);
        else if(x == 0){
            if(y & 1) printf("-1 -1\n");
            else{
                printf("0 %d\n", y >> 1);
            }
        }else if(y == 0){
            if(x & 1) printf("-1 -1\n");
            else{
                printf("%d 0\n", x >> 1);
            }
        }else{
            if(x % 2 == 0 && y % 2 == 0){
                printf("%d %d\n", x >> 1, y >> 1);
            }else{
                for(int i = 0; i <= x; i++){
                    for(int j = 0; j <= y; j++){
                        if(i + j == abs(x - i) + abs(y - j) && i + j == (x + y) >> 1){
                            printf("%d %d\n", i, j);
                            goto con;
                        }
                    }
                }
                printf("-1 -1\n");
                con: continue;
            }
        }
    }
}

B题(原题网址

大致题意

给定你 n, a, b, 要你构造一个长度为n(n为偶数)的一个数组,数组中的元素由 1 ~ n 组成,无重复数字。要求: 在左半区间a最小,右半区间b最大,若能则输出其中任意一个,若不能构造这样的区间则输出-1

AC代码
#include <iostream>
#include<algorithm>
#include <cstring>
using namespace std;
int arr[110];
bool vis[110];
int main(){
    int t;
    int n, l, r;
    scanf("%d", &t);
    while(t--){
        memset(arr, 0 , sizeof arr);
        memset(vis, false , sizeof vis);
        scanf("%d%d%d", &n, &l, &r);
        if(n - l + 1 < ( n >> 1 ) || r < (n >> 1) || max( l, r) <= (n>>1)|| min(l, r) > (n >> 1)){
            printf("-1\n");
            continue;
        }
        arr[1] = l, arr[n] = r;
        vis[l] = vis[r] = true;
        int idx = n;
        for(int i = 1 ; i <= n; i++){
            if(!arr[i]){
                while(vis[idx]) idx--;
                arr[i] = idx;
                vis[idx] = true;
            }
        }
        for(int i = 1; i <= n; i++)
            printf("%d ", arr[i]);
        printf("\n");
    
    }
}

C题(原题网址

大致题意

给定k, x,k会构成一个2 * k - 1 的图案,如下

    /*
    * k = 1
    * 排列为 -- >    
    *               *
    * k = 2
    * 排列为 -- >    
    *               *
    *               * *
    *               *
    * k = 3     
    * 排列为 -- >    
    *               *
    *               * * 
    *               * * *
    *               * *
    *               *
    */

你想在一个聊天室发由k构造而成的图案,每次发一行,而 x 则是对 * 的数量的限制。
只要你发的 * 的数量超过了 x 就会被禁言,问你发多少行会被禁言,如果都不会被禁言就输出你最多发了多少行(可自行去原题网址查看样例数据)

AC代码
#include <iostream>
#include <algorithm>
#include <cstring>
#define ll long long
using namespace std;
int main(){
    int t;
    ll k, x;
    scanf("%d", &t);
    while(t--){       
        scanf("%lld%lld", &k, &x);
        ll len = (k << 1) - 1;
        ll l = 1, r = len;
        ll sum;
        while(l <= r){
            ll mid = (l + r) >> 1;
            if(mid <= k){
                sum = (mid + 1) * mid >> 1;
                if(sum < x) l = mid + 1;
                else r = mid - 1;
            }else{
                ll lr = len - mid;
                sum = ((k + 1) * k >> 1) + ((k - 1) * k >> 1) - ((lr + 1) * lr >> 1);
                if(sum < x) l = mid + 1;
                else r = mid - 1;
            }
        }
        if(l > len) printf("%d\n", r);
        else printf("%d\n", l);
    }
}

D题(原题网址

大致题意

给定 a, b, x 你可以将 a 或 b 替换成 |a - b| (|a - b| != a 或 b) 问:在进行任意次操作后是否有 a 或 b 等于 x 的情况, 有则输出 YES 反之输出 NO

    如 a  b  c
       6  9  3
        ||
        \/  
       6  3  3 此时 b = 3 = x  
        ||    
        \/ (还可继续操作)
       3  3  3 
       
AC代码
#include <iostream>
#include <algorithm>
#include <cstring>
#define no printf("NO\n")
#define yes printf("YES\n")
#define ll long long
using namespace std;
ll ta, tb, x;
bool find(ll a, ll b){
    if(max(a, b) < x) return false;
    if(a == x || b == x || abs(a - b) == x) {
        yes;
        return true;
    }
    if(abs(a - b) == a || abs(a - b) == b) return false;
    if(a > b){
        a -= ((a - x) / b )* b;
    }else{
        b -= (b - x) / a * a;
    }
    if(a == x || b == x || abs(a - b) == x) {
        yes;
        return true;
    }
    if(find(min(a, b), abs(a - b))) return true;
    return false;
}
int main(){
    int t;
    scanf("%d", &t);
    while(t--){   
        scanf("%lld%lld%lld", &ta, &tb, &x);
        if(x > max(ta, tb)) no;
        else{
            if(ta == x || tb == x) yes;
            else if(!find(ta, tb)) no;
        }
    }
}
原文地址:https://www.cnblogs.com/slwang/p/15590605.html