2019 China Collegiate Programming Contest Qinhuangdao Onsite

目录

  • Contest Info
  • Solutions
    • A. Angle Beats
    • D. Decimal
    • F. Forest Program
    • I. Invoker
    • J. MUV LUV EXTRA

Contest Info



Practice Link

Solved A B C D E F G H I J K L
5/12 O - - O - O - - - O ? -
  • O 在比赛中通过
  • ? 赛后通过
  • ! 尝试了但是失败了
  • - 没有尝试

Solutions


A. Angle Beats

题意:
给出\(n\)个点,每次询问再给出一个点,询问\(n\)个点中与当前这个点构成直角三角形的方案数。

D. Decimal

题意:
给出一个\(n\),判断\(\frac{1}{n}\)是否是一个无限循环小数。

思路:
如果\(n\)的质因子分解是\(2^x5^y\)那么不是无限循环

代码:

view code

#include <bits/stdc++.h>
#define debug(...) { printf("#  "); printf(__VA_ARGS__); puts(""); }
#define fi first
#define se second
#define endl "\n"
using namespace std;
using db = double;
using ll = long long;
using ull = unsigned long long;
using pII = pair <int, int>;
using pLL = pair <ll, ll>;
constexpr int mod = 1e9 + 7;
template <class T1, class T2> inline void chadd(T1 &x, T2 y) { x += y; while (x >= mod) x -= mod; while (x < 0) x += mod; }
template <class T1, class T2> inline void chmax(T1 &x, T2 y) { if (x < y) x = y; }
template <class T1, class T2> inline void chmin(T1 &x, T2 y) { if (x > y) x = y; }
inline int rd() { int x; cin >> x; return x; }
template <class T> inline void rd(T &x) { cin >> x; }
template <class T> inline void rd(vector <T> &vec) { for (auto &it : vec) cin >> it; }
inline void pt() { cout << endl; }
template <class T, class... Ts> void pt(const T& arg, const Ts&... args) { cout << arg << " "; pt(args...); }
template <class T> inline void pt(const T &s) { cout << s << "\n"; }
template <class T> inline void pt(const vector <T> &vec) { for (auto &it : vec) cout << it << " "; cout << endl; }
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
inline ll qpow(ll base, ll n) { ll res = 1; while (n) { if (n & 1) res = res * base % mod; base = base * base % mod; n >>= 1; } return res; }
constexpr int N = 1e5 + 10;
int n;
void run() {
    cin >> n;
    while (n % 2 == 0) n /= 2;
    while (n % 5 == 0) n /= 5;
    if (n == 1) pt("No");
    else pt("Yes");
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);
    cout << fixed << setprecision(20);
    int _T; cin >> _T;
    while (_T--) run();
    return 0;
}

F. Forest Program

题意:
给出一个无向图,每条边最多存在于一个环中,问多少种移除边的方案使得剩下的每一个连通块都是一棵树

思路:
一个环,这个环上至少要切一条边,其他边任意切不切。
注意刚开始给出的可能不是连通图。

代码:

view code

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 5e5 + 10;
const ll mod = 998244353;
int n, m, bit[N];
vector <vector<int>> G;
int dep[N], tot, vis[N], Insta[N]; ll res;
void dfs(int u, int pre) {
    vis[u] = 1;
    Insta[u] = 1;
    for (auto &v : G[u]) if (v != pre) {
        if (Insta[v]) {
            tot -= dep[u] - dep[v] + 1;
            res = 1ll * res * (bit[dep[u] - dep[v] + 1] - 1) % mod;
            res %= mod;
        }
        if (!vis[v]) {
            dep[v] = dep[u] + 1;
            dfs(v, u);
        }
    }
    Insta[u] = 0;
}

int main() {
    bit[0] = 1;
    for (int i = 1; i < N; ++i) bit[i] = 1ll * bit[i - 1] * 2 % mod;
    while (scanf("%d%d", &n, &m) != EOF) {
        G.clear(); G.resize(n + 1);
        for (int i = 1; i <= n; ++i) dep[i] = vis[i] = Insta[i] = 0;
        for (int i = 1, u, v; i <= m; ++i) {
            scanf("%d%d", &u, &v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        tot = m; res = 1;
        for (int i = 1; i <= n; ++i) if (!vis[i]) dfs(i, i);
        res = 1ll * res * bit[tot] % mod;
        res = (res + mod) % mod;
        printf("%lld\n", res);
    }
    return 0;
}

I. Invoker

题意:
每种技能需要三种属性,三个属性被按下就可以触发,而顺序不重要。
但是每次只能保留三个属性,按下第四个的时候第一个会被移除。
现在给出一个需要使用的技能表,询问怎样按键使得按顺序出发这些技能并且按下的次数最少。

思路:
考虑每种技能最多只有六种排列状态,那么\(f[i][S]\)表示前\(i\)个技能,当前排列状态为\(S\)的最少按键数。

代码:

view code

#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 10;
char s[N]; int n;
map <string, int> f[2];
map <char, string> mp;

int main() {
    mp['Y'] = "QQQ";
    mp['V'] = "QQW";
    mp['G'] = "EQQ";
    mp['C'] = "WWW";
    mp['X'] = "QWW";
    mp['Z'] = "EWW";
    mp['T'] = "EEE";
    mp['F'] = "EEQ";
    mp['D'] = "EEW";
    mp['B'] = "EQW";
    while (scanf("%s", s + 1) != EOF) {
        f[0].clear(), f[1].clear();
        int n = strlen(s + 1);
        for (int i = 1; i <= n; ++i) {
            int p = i & 1;
            if (i > 1 && s[i] == s[i - 1]) {
                f[p] = f[p ^ 1];
                continue;
            }
            f[p].clear();
            string s1 = mp[s[i]];
        //    cout << s1 << endl;
            do {
                if (i == 1) {
                    f[p][s1] = 3;
                    continue;
                }
                f[p][s1] = 1e9;
                for (auto &it : f[p ^ 1]) {
                    string s2 = it.first;
                //    cout << s1 << " " << s2 << endl;
                    int w = it.second;
                    if (s2[1] == s1[0] && s2[2] == s1[1]) {
                        f[p][s1] = min(f[p][s1], w + 1);
                    } else if (s2[2] == s1[0]) {
                        f[p][s1] = min(f[p][s1], w + 2);
                    } else {
                        f[p][s1] = min(f[p][s1], w + 3);
                    }
                }
            }while (next_permutation(s1.begin(), s1.end()));
        }
        int res = 1e9;
        for (auto &it : f[n & 1]) {
        //    cout << it.first << " " << it.second << endl;
            res = min(res, it.second);
        }
        printf("%d\n", res + n);
    }
    return 0;
}

J. MUV LUV EXTRA

题意:
给出一个小数,询问小数部分后缀中的\(a \cdot p - b \cdot l\)的最大值。
\(a, b\)是参数,\(p\)表示循环节长度,\(l\)表示后缀长度

思路:
将字符串翻转,用\(kmp\)找循环节即可。

代码:

view code

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int N = 1e7 + 10;
ll a, b;
char s[N], t[N]; int n;
void get() {
    int i;
    for (i = 1; s[i]; ++i) {
        if (s[i] == '.') break;
    }
    n = 0;
    for (++i; s[i]; ++i) {
        t[n++] = s[i];
    }
    t[n] = 0;
}
struct KMP {
    int Next[N];
    //下标从0开始
    void get_Next(char *s) {
        int len = strlen(s);
        int i, j;
        j = Next[0] = -1;
        i = 0;
        while (i < len) {
            while (-1 != j && s[i] != s[j]) j = Next[j];
            Next[++i] = ++j;
        }
    }
}kmp;

int main() {
    while (scanf("%lld%lld", &a, &b) != EOF) {
        scanf("%s", s + 1);
        get();
        reverse(t, t + n); t[n] = 0;
        kmp.get_Next(t);
        ll res = a - b;
        for (int i = 1; i < n; ++i) {
            ll p = i + 1;
        //    cout << i << " " << kmp.Next[i + 1] << endl;
            ll l = p - kmp.Next[i + 1];
            res = max(res, a * p - b * l);
        }
        printf("%lld\n", res);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/Dup4/p/11718018.html

时间: 2024-10-11 03:59:22

2019 China Collegiate Programming Contest Qinhuangdao Onsite的相关文章

The 2019 China Collegiate Programming Contest Harbin Site F. Fixing Banners

链接: https://codeforces.com/gym/102394/problem/F 题意: Harbin, whose name was originally a Manchu word meaning "a place for drying fishing nets", grew from a small rural settlement on the Songhua River to become one of the largest cities in Northea

The 2019 China Collegiate Programming Contest Harbin Site

目录 Contest Info Solutions A. Artful Paintings E. Exchanging Gifts F. Fixing Banners I. Interesting Permutation J. Justifying the Conjecture K. Keeping Rabbits L. LRU Algorithm Contest Info Practice Link Solved A B C D E F G H I J K L 6/12 O - - - O O

The 2019 China Collegiate Programming Contest Harbin Site K. Keeping Rabbits

链接: https://codeforces.com/gym/102394/problem/K 题意: DreamGrid is the keeper of n rabbits. Initially, the i-th (1≤i≤n) rabbit has a weight of wi. Every morning, DreamGrid gives the rabbits a carrot of weight 1 and the rabbits fight for the only carrot

The 2019 China Collegiate Programming Contest Harbin Site J. Justifying the Conjecture

链接: https://codeforces.com/gym/102394/problem/J 题意: The great mathematician DreamGrid proposes a conjecture, which states that: Every positive integer can be expressed as the sum of a prime number and a composite number. DreamGrid can't justify his c

The 2019 China Collegiate Programming Contest Harbin Site I. Interesting Permutation

链接: https://codeforces.com/gym/102394/problem/I 题意: DreamGrid has an interesting permutation of 1,2,-,n denoted by a1,a2,-,an. He generates three sequences f, g and h, all of length n, according to the permutation a in the way described below: For ea

The 2019 China Collegiate Programming Contest Harbin Site I - Interesting Permutation 思维

//#include<bits/stdc++.h> #include<map> #include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define int long long using namespace std; #define rep_1(i,m,n) for(int i=m;i<=n

The 2019 China Collegiate Programming Contest Harbin Site A - Artful Paintings 差分约束

#include<map> #include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define ll long long const int N=1e5+5; const int M=1e5+5; const int INF=0x3f3f3f3f; int read(

The 2019 China Collegiate Programming Contest Harbin Site E - Exchanging Gifts 拓扑图+离散化

非常难受的是,我用链表写的,要么wa,要么tle,甚至还出现了超内存... 然后换成矩阵,开始还是wa了两次,然后换了别的快读,才过,难受. #include<map> #include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; #

2018 China Collegiate Programming Contest Final (CCPC-Final 2018)(A B G I L)

A:签到题,正常模拟即可. 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn = 1e5 + 5; 4 struct node{ 5 int id, time; 6 }; 7 node a[maxn]; 8 bool cmp(const node &a, const node &b){ 9 if(a.id^b.id) return a.id < b.id; 10 else return a.