zoukankan      html  css  js  c++  java
  • 2018 ccpc final

     

    2018 CCPC FINAL

    kunkun全球后援队训练赛赛

    A.

    签到

    笨比mwh wa了两发

    #include <stdio.h>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cmath> 
    #pragma GCC optimize(2)
    
    using namespace std;
    typedef long long ll;
    const int N = 1e5 + 5;
    int t, n, m, kas;
    
    struct node{
        int d, t;
    }list[N];
    
    bool cmp(node a, node b){
        if (a.d == b.d) return a.t < b.t;
        return a.d < b.d;
    }
    
    int main()
    {
    //    cin.tie(0);
    //    cout.tie(0);
    //    ios::sync_with_stdio(0);
        cin >> t;
        kas = 0;
        while (t--)
        {
            cin >> n >> m;
            for (int i = 0; i < n; ++i)
                cin >> list[i].d;
            for (int i = 0; i < n; ++i)
                cin >> list[i].t;
                
            sort(list, list + n, cmp);
            
            int ans = 0;
            int x = 0;
            for (int i = 0; i < n; ++i)
            {
                x += list[i].t;
                if (x <= m)
                    ans++;
                else
                    break;
            }
            printf("Case %d: %d
    ", ++kas, ans);
        }
    }
    View Code

    L

    数学  思维

    看了样例,一开始的想法是把这个数字先除以6,然后再找。(当然找不到了)

    然后发现题目给了条件

    A weaker version of this conjecture states that every odd number greater than 5 is the sum of three prime numbers.

    顺其自然的就想到解法

    先找到比n小且和n的差大于等于11的最大素数tmp (tmp就是要找的6个素数中的一个), 得到 n - tmp , 如果 n - tmp 是奇数, 就把它减去4, 输出 2  2,如果 n - tmp 是偶数, 就把它减去5, 输出 2  3。由于题目给出的结论, 剩下的数是肯定可以由3个素数组成的。因为我们之前减的tmp是最大的满足条件的素数,所以剩余的素数应该非常小,可以直接暴力。

    #include <stdio.h>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #define REP(i,k,n) for(int i=k;i<=n;i++)
    #pragma GCC optimize(2)
    
    using namespace std;
    typedef long long ll;
    int t, ind;
    ll n;
    
    const int N = 1e5 + 5;
    int prime[10000010],book[10000010];
    
    void turn(int p)
    {
        for(int i = 2; i <= p; i++)
            {
            if(!book[i])  prime[++ind]=i;//如果没有筛过,记录素数
            REP(j,1,ind){//其中记录数组里的素数保证严格递增
                if(i*prime[j]>p)  break;//保证小于n,要不然没有意义
                book[i*prime[j]]=1;//筛去这个合数
                if(!i%prime[j])  break;//如果>=这个数的最小质因子,那就结束
            }
        }
    }
    
    bool check(ll n){
        ll tmp = sqrt(n);
        for (int i = 2; i <= tmp; ++i)
            if (n % i == 0)
                return false;
        return true;
    }
    
    int main()
    {
        turn(100000);
        cin >> t;
        int kas = 0;
        while (t--)
        {
            scanf("%lld", &n);
            if (n == 12)
            {
                printf("Case %d: 2 2 2 2 2 2
    ", ++kas);
                continue;
            }
            ll tmp;
            
            if (n <= 11)
            {
                printf("Case %d: IMPOSSIBLE
    ", ++kas);
                continue;
            }
            
            for (ll i = n - 11; i >= 0; --i)
            {
                if (check(i))
                {
                    tmp = i;
                    break;
                }
            }
            
            n = n - tmp;
            int flag;
            
            if (n & 1)
            {
                n -= 4;
                flag = 1;
            }
            else
            {
                n -= 5;
                flag = 2;
            }
            
            for (ll i = 1; i <= 9592; ++i)
            {
                for (ll j = 1; j <= 9592; ++j)
                {
                    if (check(n - prime[i] - prime[j]) && n - prime[i] - prime[j] > 0)
                    {
                        if (flag == 1)
                        {
                            printf("Case %d: 2 2 %lld %d %d %d
    ", ++kas, tmp, prime[i], prime[j], n - prime[i] - prime[j]);
                            flag = -1;
                            break;
                        }
                        else
                        {
                            printf("Case %d: 2 3 %lld %d %d %d
    ", ++kas, tmp, prime[i], prime[j], n - prime[i] - prime[j]);
                            flag = -1;
                            break;
                        }
                    }
                }
                if (flag == -1)
                    break;
            }
            
        }
    }
    View Code

    G

    找规律  逆元

    直接dfs搜

    打表程序找出规律,推出公式,注意mod的时候要逆元

    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    
    typedef long long ll;
    const ll mod = 1e9+7;
    using namespace std;
    ll t, m, n;
    ll solve(ll n) {
        return n * (n + 1) / 2;
    }
    ll quick_m(ll a, ll x) {
        ll ans =1;
        while (x) {
            if (x&1) {
                ans = ans * a % mod;
            }
            x>>=1;
            a = a * a % mod;
        }
        return ans;
    }
    int main () {
        scanf("%d", &t);
        int kas = 0;
        while (t--) {
            scanf("%lld%lld", &n, &m);
            if (n < 3 || m < 3) {
                printf("Case %d: %d
    ", ++kas, 0);
                continue;
            } else if (m == 3 && n == 3) {
                printf("Case %d: %d
    ", ++kas, 1);
                continue;
            } else if (n > 7 && m > 7) {
                ll ans = 1;
    //            n--;
    //            m--;
                ans = ans * m % mod;
                ans = ans * (m-1) % mod;
                ans = ans * (m-2) % mod;
                ans = ans * (m+1) % mod;
    //            ans = ans * a[n] % mod;
                ans = ans * quick_m(24, mod-2) % mod;
                ans = ans * n % mod;
                ans = ans * (n-1) % mod;
                ans = ans * (n-2) % mod;
                ans = ans * (n+1) % mod;
    //            ans = ans * a[m] % mod;
                ans = ans * quick_m(24, mod-2) % mod;
                printf("Case %d: %lld
    ", ++kas, ans);
            } else {
                n -= 2;
                m -= 2;
                ll ans1 = 0, ans2 = 0;
                for (ll i = 1; i <= n; i++) {
                    ans1 = (ans1 + solve(i) * (n-i+1)) % mod;
                }
                for (ll j = 1; j <= m; j++) {
                    ans2 = (ans2 + solve(j) * (m-j+1)) % mod;
                }
                printf("Case %d: %lld
    ", ++kas, ans1*ans2 % mod);
            }
            
        }
        return 0;
    }
    View Code

    正解

    题目意思可以理解为寻找i两个子矩阵,推出公式 () 

    https://blog.csdn.net/Tony5t4rk/article/details/88054604?tdsourcetag=s_pctim_aiomsg

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn = 1e5 + 5;
    const int mod = 1e9 + 7;
    
    ll C[maxn][5];
    
    void Init() {
        C[0][0] = 1;
        for (int i = 1; i < maxn; ++i) {
            C[i][0] = 1;
            for (int j = 1; j < 5; ++j) C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % mod;
        }
    }
    
    int main() {
        ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
        Init();
        int t; cin >> t;
        for (int Case = 1; Case <= t; ++Case) {
            int n, m; cin >> n >> m;
            if (n < 3 || m < 3) {
                cout << "Case " << Case << ": " << 0 << endl;
                continue;
            }
            cout << "Case " << Case << ": " << ((C[n][3] + C[n][4]) % mod) * ((C[m][3] + C[m][4]) % mod) % mod << endl;
        }
        return 0;
    }
    View Code

    L

    没打出来

    等待补提,贴一个隔壁队大神的代码

    //zyh
    #include <stdio.h>
    #include <algorithm>
    #include <vector>
    #include <set>
    #include <cstring>
    using namespace std;
    
    typedef long long ll; 
    const int N = 1e5+10;
    int numx[N], numy[N], connumy[N], connumx[N];
    vector <int> vex, vey;
    set <int> st[N];
    struct node{
        int x, y;
    }a[N];
    int newyid[N], newxid[N];
    bool cmpy(int x, int y)
    {
        return numy[x] > numy[y];
    }
    bool cmpx(int x, int y)
    {
        return numx[x] > numx[y];
    }
    set <int> :: iterator it;
    int main()
    {
    //    freopen("1.txt", "r", stdin);
        int T, n, ca=0, x, y;
        scanf("%d", &T);
        while(T--)
        {
            memset(numx, 0, sizeof(numx));
            memset(numy, 0, sizeof(numy));
            memset(connumy, 0, sizeof(connumy));
            memset(connumx, 0, sizeof(connumx));
            scanf("%d", &n);
            for(int i = 1; i <= n; i++) st[i].clear();
            vex.clear(); vey.clear();
            for(int i = 1; i <= n; i++)
            {
                scanf("%d %d", &a[i].x, &a[i].y);
                vex.push_back(a[i].x);
                vey.push_back(a[i].y);
            }
            
            sort(vex.begin(), vex.end());
            vex.erase(unique(vex.begin(), vex.end()), vex.end());
            
            sort(vey.begin(), vey.end());
            vey.erase(unique(vey.begin(), vey.end()), vey.end());
            
            for(int i = 1; i <= n; i++)
            {
                x = lower_bound(vex.begin(), vex.end(), a[i].x)-vex.begin()+1;
                y = lower_bound(vey.begin(), vey.end(), a[i].y)-vey.begin()+1;
                numx[x]++;
                connumx[x]++;
                numy[y]++;
                connumy[y]++;
                st[x].insert(y);
            }
            
            int sizey = vey.size(), sizex = vex.size();
            
            for(int i = 1; i <= sizey; i++) newyid[i] = i;
            for(int i = 1; i <= sizex; i++) newxid[i] = i;
            
            sort(newyid+1, newyid+1+sizey, cmpy);
            sort(newxid+1, newxid+1+sizex, cmpx);
            
            sort(numx+1, numx+1+sizex, greater<int>());
            
            sort(numy+1, numy+1+sizey, greater<int>());
            
            ll res = 0, num = 0;
            
            for(int i = 1; i <= sizex; i++)
            {
                if(numx[i]+numy[1] <= res) continue;
                for(int j = 1; j <= sizey; j++)
                {
                    int tmp = st[newxid[i]].count(newyid[j]);
                    if(numx[i]+numy[j]-tmp>res)
                    res = numx[i]+numy[j]-tmp;
                    if(tmp == 0) break;
                }
            }
            
            for(int i = 1; i <= n; i++)
            {
                x = lower_bound(vex.begin(), vex.end(), a[i].x)-vex.begin()+1;
                y = lower_bound(vey.begin(), vey.end(), a[i].y)-vey.begin()+1;
                if(connumx[x]+connumy[y]==res+1) 
                num++;
            }
            for(int i = 1; i <= sizex; i++)
            {
                int s = lower_bound(numy+1, numy+1+sizey, res-numx[i], greater<int>()) - numy;
                int e = upper_bound(numy+1, numy+1+sizey, res-numx[i], greater<int>()) - numy - 1;
                int tmp = e - s + 1;
                for(it = st[newxid[i]].begin(); it != st[newxid[i]].end(); it++)
                {
                    if(connumy[*it]==res-numx[i]) tmp--;
                }
                num += tmp;
            }
            if(res==2) num /= 2;
            printf("Case %d: %lld %lld
    ", ++ca, res, num);
        }    
    }
    View Code

    膜yh大神 ORZ

  • 相关阅读:
    codevs1127
    codevs1041
    C#预处理指令
    C#基本语句与C++区别
    iOS.TextKit.01.凸版印刷效果
    iOS.常用设计模式.02.委托模式
    iOS.常用设计模式.01.单例模式
    iOS.iPad.03.UIModal
    iOS.iPad.02.UIPopoverViewController
    iOS.iPad.01.UISplitViewController
  • 原文地址:https://www.cnblogs.com/mwh123/p/11667746.html
Copyright © 2011-2022 走看看