$CF 639 (Div2)$

Posted chenyangxu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了$CF 639 (Div2)$相关的知识,希望对你有一定的参考价值。

(CF 639 (Div2))

(A.)

判断给定拼图是否可拼

找规律发现,只有 (1 imes m, n imes 1, 2 imes 2) 的可行

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <math.h>
#include <algorithm>
#include <vector>
#define fi first
#define se second
#define pii pair<int, int>
#define pb push_back
#define arrayDebug(a, l, r) for(int i = l; i <= r; ++i) printf("%d%c", a[i], " 
"[i == r])
typedef long long LL;
typedef unsigned long long ULL;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int DX[] = {0, -1, 0, 1, 0, -1, -1, 1, 1};
const int DY[] = {0, 0, 1, 0, -1, -1, 1, 1, -1};
const int MOD = 1e9;
const int N = 5e5 + 7;
const double PI = acos(-1);
const double EPS = 1e-6;
using namespace std;
inline int read()
{
    char c = getchar();
    int ans = 0, f = 1;
    while(!isdigit(c)) {if(c == ‘-‘) f = -1; c = getchar();}
    while(isdigit(c)) {ans = ans * 10 + c - ‘0‘; c = getchar();}
    return ans * f;
}
 
int t;
int main()
{
    t = read();
    while(t--) {
        int n = read(), m = read();
        if(n == 1 || m == 1 || m == 2 && n == 2) puts("YES");
        else puts("NO");
    }
    return 0;
}
/*
5 5
1 2
2 5
5 4
4 3
3 1
*/

(B.)

给定高度为 (h) 的卡堆的堆积方式以及 (n) 张卡片,优先建造高度最高的卡堆,计算可构造的卡堆的最大数量

(dp[i]) 表示高度为 (i) 的卡堆所需卡片数量,找规律发现

[dp[i] = dp[i - 1] + 3 i - 1 ]

预处理各个卡堆所需要的卡片数量,对于当前的 (n),不断二分查找可构造的最大卡堆即可

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <math.h>
#include <algorithm>
#include <vector>
#define fi first
#define se second
#define pii pair<int, int>
#define pb push_back
#define arrayDebug(a, l, r) for(int i = l; i <= r; ++i) printf("%d%c", a[i], " 
"[i == r])
typedef long long LL;
typedef unsigned long long ULL;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int DX[] = {0, -1, 0, 1, 0, -1, -1, 1, 1};
const int DY[] = {0, 0, 1, 0, -1, -1, 1, 1, -1};
const int MOD = 1e9;
const int N = 1e5 + 7;
const double PI = acos(-1);
const double EPS = 1e-6;
using namespace std;
inline int read()
{
    char c = getchar();
    int ans = 0, f = 1;
    while(!isdigit(c)) {if(c == ‘-‘) f = -1; c = getchar();}
    while(isdigit(c)) {ans = ans * 10 + c - ‘0‘; c = getchar();}
    return ans * f;
}
 
int t;
LL dp[N];
int main()
{
    dp[1] = 2;
    int cnt = 0;
    for(int i = 2; i <= N; ++i) {
        cnt++, dp[i] = dp[i - 1] + 3 * i - 1;
        if(dp[i] >= 1000000000) break;
    }
    //for(int i = 1; i <= cnt; ++i) dp[i] += dp[i - 1];
    t = read();
    while(t--) {
        int n = read();
        int ans = 0;
        while(n) {
            int p = upper_bound(dp + 1, dp + 1 + cnt, n) - dp;
            p--;
            if(p > 0 && dp[p] <= n) ans++, n -= dp[p];
            else break;
        }
        printf("%d
", ans);
    }
    return 0;
}
/*
5
3
14
15
24
1
*/

(C.)

有无限个房间,每个房间对应唯一一个数字,每个房间初始有一个客人

给定长为 (n) 的整数序列 (a)

现在移动客人,将 (k) 房间内的客人移动到房间 (k + a_{k mod n}),询问移动后是否仍然满足每个房间至多只有 (1) 个客人

假设 (a_{k mod n} = a_{0}),当然也可以等于其他位置

考虑移动的映射关系

(k ightarrow k + a_{k mod n} = k + a_{0})

(k + 1 ightarrow k + 1 + a_{(k + 1) mod n} = k + 1 + a_{1})

(k + 2 ightarrow k + 2 + a_{(k + 2) mod n} = k + 2 + a_{2})

(...)

(k + n - 1 ightarrow k + n - 1 + a_{(k + n - 1) mod n} = k + n - 1 + a_{n - 1})

(k + n ightarrow k + n + a_{(k + n) mod n} = k + n + a_{0})

分析得到,只需要 (i + a[i], i = 0, 1, ..., n - 1) 构成模 (n) 的一个最小非负完全剩余系即可

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int, int>
#define pb push_back
#define arrayDebug(a, l, r) for(int i = l; i <= r; ++i) printf("%d%c", a[i], " 
"[i == r])
typedef long long LL;
typedef unsigned long long ULL;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int DX[] = {0, -1, 0, 1, 0, -1, -1, 1, 1};
const int DY[] = {0, 0, 1, 0, -1, -1, 1, 1, -1};
const int MOD = 1e9;
const int N = 2e5 + 7;
const double PI = acos(-1);
const double EPS = 1e-6;
using namespace std;
inline int read()
{
    char c = getchar();
    int ans = 0, f = 1;
    while(!isdigit(c)) {if(c == ‘-‘) f = -1; c = getchar();}
    while(isdigit(c)) {ans = ans * 10 + c - ‘0‘; c = getchar();}
    return ans * f;
}

int t;
LL n, a[N];
int main()
{
    t = read();
    while(t--) {
        n = read();
        for(int i = 0; i < n; ++i) scanf("%lld", &a[i]);
        set<LL> st;
        for(int i = 0; i < n; ++i) {
            st.insert(((a[i] + i) % n + n) % n);
        }
        if(st.size() == n) puts("YES");
        else puts("NO");
    }
    return 0;
}
/*
5
3
14
15
24
1
*/

这题想通了还是挺有意思的 ??

以上是关于$CF 639 (Div2)$的主要内容,如果未能解决你的问题,请参考以下文章

CodeForces Round #639 div2 前三题

CodeForces Round #639 div2 前三题

CF639F Bear and Chemistry

CF600 div2 F.Cheap Robot

cf386(div2)大一狗ACM之路

# $CF 638 (Div2)$