zoukankan      html  css  js  c++  java
  • 2016 CCPC 长春 Solution

    A - Hanzo vs. Genji

    留坑。

    B - Fraction

    水。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 inline int gcd(int a, int b)
     5 {
     6     return b ? gcd(b, a % b) : a; 
     7 }
     8 
     9 int t, n;
    10 int a[10], b[10];
    11 
    12 int main()
    13 {
    14     scanf("%d", &t);
    15     for (int kase = 1; kase <= t; ++kase)
    16     {
    17         scanf("%d", &n);
    18         for (int i = 1; i <= n; ++i) scanf("%d", a + i);
    19         for (int i = 1; i <= n; ++i) scanf("%d", b + i);
    20         int p = b[n], q = a[n];
    21         for (int i = n - 1; i >= 1; --i)
    22         {
    23             int tq = a[i] * q + p; 
    24             int tp = b[i] * q;
    25             p = tp, q = tq;
    26             int Gcd = gcd(p, q); p /= Gcd, q /= Gcd;
    27         }
    28         int Gcd = gcd(p, q); p /= Gcd, q /= Gcd;
    29         printf("Case #%d: %d %d
    ", kase, p, q);
    30     }
    31     return 0;
    32 }
    View Code

    C - Rotate String

    留坑。

    D - Triangle

    水。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 int fic[25];
     5 
     6 int t, n;
     7 
     8 int main()
     9 {
    10     fic[0] = fic[1] = 1;
    11     for (int i = 2; i <= 20; ++i) fic[i] = fic[i - 1] + fic[i - 2];
    12     scanf("%d", &t);
    13     for (int kase = 1; kase <= t; ++kase)
    14     {
    15         scanf("%d", &n);
    16         int pos = upper_bound(fic + 1, fic + 21, n) - fic;
    17         printf("Case #%d: %d
    ", kase, n - pos + 1);
    18     }
    19     return 0;
    20 }
    View Code

    E - The Fastest Runner Ms. Zhang

    留坑。

    F - Harmonic Value Description

    题意:有一个1-n的全排列,定义一个值$sum_{i = 1}^{i = n - 1} gcd(p_i, p_{i + 1})$ 求这个值第k大的数列

    思路:首先相邻的奇数的gcd为1,相邻的偶数的gcd为2

    分类讨论:k=1输出原序列

    k为偶数,将k和2*k提前输出在按照原序列输出,提供的贡献就是k-1

    k为奇数,将3开始的k-1个奇数提前,其他按照原序列输出,每个奇数的提前会导致左右的偶数产生贡献为2

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 #define N 10010
     6 
     7 int n, k;
     8 int arr[N];
     9 int vis[N];
    10 
    11 int main()
    12 {
    13     int t;
    14     scanf("%d",&t);
    15     for(int cas = 1; cas <= t; ++cas)
    16     {
    17         scanf("%d %d",&n, &k);
    18         printf("Case #%d:", cas);
    19         memset(vis, 0, sizeof vis);
    20         if(k == 1)
    21         {
    22             for(int i = 1; i <= n; ++i) arr[i] = i;
    23         }
    24         else if(k % 2 == 0)
    25         {
    26             arr[1] = k;
    27             arr[2] = 2 * k;
    28             int cnt = 3;
    29             for(int i = 1; i <= n; ++i)
    30             {
    31                 if(i == k || i == 2 * k) continue;
    32                 arr[cnt++] = i;
    33             }
    34         }
    35         else 
    36         {
    37             int cnt = 1;
    38             int num = 3;
    39             for(int i = 1; i < k; ++i)
    40             {
    41                 arr[cnt++] = num;
    42                 vis[num] = 1;
    43                 num += 2;
    44             }
    45             for(int i = 1; i <= n; ++i)
    46             {
    47                 if(vis[i]) continue;
    48                 arr[cnt++] = i;
    49             }
    50         }
    51         for(int i = 1;  i <= n; ++i) printf(" %d", arr[i]);
    52         printf("
    ");
    53     }
    54     return 0;
    55 }
    View Code

    G - Instability

    题意:有n个点,m条边,求有多少个点的子集,使得这个子集中点的个数$>= 3$  并且这个子集中存在三个点互相可达,或者互相不可达

    思路:根据拉姆齐定理,当点数$>= 6$ 的时候,必然存在这种情况,对于点数3, 4, 5 直接暴力求解

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 #define ll long long
      5 
      6 const ll MOD = (ll)1e9 + 7;
      7 
      8 ll fac[60], inv[60];
      9 
     10 inline ll qpow(ll base, ll n)
     11 {
     12     ll res = 1;
     13     while (n)
     14     {
     15         if (n & 1) res = res * base % MOD;
     16         base = base * base % MOD;
     17         n >>= 1;
     18     }
     19     return res; 
     20 }
     21 
     22 inline void Fac_Init()
     23 {
     24     fac[0] = 1;
     25     for (int i = 1; i < 60; ++i)
     26         fac[i] = fac[i - 1] * i % MOD;
     27     inv[59] = qpow(fac[59], MOD - 2);
     28     for (int i = 58; i >= 0; --i)
     29         inv[i] = inv[i + 1] * (i + 1) % MOD;
     30 }
     31 
     32 inline ll C(int a, int b)
     33 {
     34     if (b > a) return 0;
     35     if (b == 0) return 1;
     36     return fac[a] * inv[b] % MOD * inv[a - b] % MOD;
     37 }
     38 
     39 //ll C[55][55];
     40 //
     41 //void I() {
     42 //    for (int i = 0; i < 55; i++) C[i][0] = 1;
     43 //    for (int i = 1; i < 55; i++) {
     44 //        for (int j = 1; j <= i; j++) {
     45 //            C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % MOD;
     46 //        }
     47 //    }
     48 //}
     49 
     50 int t, n, m;
     51 bool G[60][60];
     52 int a[5]; 
     53 
     54 inline bool ok(int sz)
     55 {
     56     for (int i = 0; i < sz; ++i)
     57         for (int j = i + 1; j < sz; ++j)
     58             for (int k = j + 1; k < sz; ++k)
     59             {
     60                 if (G[a[i]][a[j]] && G[a[j]][a[k]] && G[a[i]][a[k]]) return true;
     61                 if (!G[a[i]][a[j]] && !G[a[j]][a[k]] && !G[a[i]][a[k]]) return true;
     62             }
     63     return false;
     64 }
     65 
     66 inline ll work()
     67 {
     68     ll res = 0;
     69     for (a[0] = 1; a[0] <= n; ++a[0])
     70         for (a[1] = a[0] + 1; a[1] <= n; ++a[1])
     71             for (a[2] = a[1] + 1; a[2] <= n; ++a[2])
     72             {
     73                 if (ok(3)) res = (res + 1) >= MOD ? (res + 1 - MOD) : (res + 1);
     74                 for (a[3] = a[2] + 1; a[3] <= n; ++a[3])
     75                 {
     76                     if (ok(4)) res = (res + 1) >= MOD ? (res + 1 - MOD) : (res + 1);
     77                     for (a[4] = a[3] + 1; a[4] <= n; ++a[4])
     78                         if (ok(5)) res = (res + 1) >= MOD ? (res + 1 - MOD) : (res + 1);
     79                 }
     80             }
     81     return res;
     82 }
     83 
     84 inline void Run() 
     85 {
     86     Fac_Init();
     87     scanf("%d", &t);
     88     for (int kase = 1; kase <= t; ++kase)
     89     {
     90         printf("Case #%d: ", kase); 
     91         scanf("%d%d", &n, &m); 
     92         memset(G, 0, sizeof G);
     93         for (int i = 1, u, v; i <= m; ++i)
     94         {
     95             scanf("%d%d", &u, &v);
     96             G[u][v] = G[v][u] = 1; 
     97         }
     98         ll ans = 0;
     99         if (n >= 6) 
    100         {
    101             for (int i = 6; i <= n; ++i)
    102                 ans = (ans + C(n, i)) % MOD;
    103         }
    104         ans = (ans + work()) % MOD;
    105         printf("%lld
    ", ans);
    106     }
    107 }
    108 
    109 int main()
    110 {
    111     #ifdef LOCAL  
    112         freopen("Test.in", "r", stdin);    
    113     #endif   
    114 
    115     Run();  
    116     return 0;  
    117 }  
    View Code

    H - Sequence I

    题意:给出$arr[]$和$brr[]$ 给出p 求有多少个q  满足 $a_q, a_{q + p}, a_{q + 2p}.....a_{q + (m - 1)p}$ 和$brr[]$ 能够匹配上

    思路:多次KMP  注意求nx数组的时候,要用模板中的第一个,不知道为啥。

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 #define N 1000010
     6 
     7 int arr[N];
     8 int brr[N];
     9 
    10 int n, m, p;
    11 
    12 inline void preKMP(int x[], int m, int kmpNext[])
    13 {
    14     int i, j;
    15     j = kmpNext[0] = -1;
    16     i = 0;
    17     while(i < m)
    18     {
    19         while(-1 != j && x[i] != x[j]) j = kmpNext[j];
    20         kmpNext[++i] = ++j;
    21     }        
    22 }
    23 
    24 int nxt[N];
    25 
    26 int KMP_count(int x[], int m, int y[], int n)
    27 {
    28     preKMP(x, m, nxt);
    29     int ans = 0;
    30     for(int k = 0; k < p; ++k)
    31     {
    32         int i = k, j = 0;
    33         while(i < n)
    34         {
    35             while(j != -1 && y[i] != x[j]) j = nxt[j];
    36             i += p;j++;
    37             if(j >= m)
    38             {
    39                 ans++;
    40                 j = nxt[j];
    41             }
    42         }    
    43     }
    44     return ans;
    45 }
    46 
    47 int main()
    48 {
    49     int t;
    50     scanf("%d", &t);
    51     for(int cas = 1; cas <= t; ++cas)
    52     {
    53         scanf("%d %d %d",&n, &m, &p);
    54         for(int i = 0; i < n; ++i) scanf("%d", arr + i);
    55         for(int i = 0; i < m; ++i) scanf("%d", brr + i);
    56         int ans = KMP_count(brr, m, arr, n);
    57         printf("Case #%d: %d
    ", cas, ans);
    58     }
    59     return 0;
    60 }
    View Code

    I - Sequence II

    题意:给出一个$arr[]$ ,每次询问给出l, r  求这个区间内第一次出现的数中,第K个数的下标

    思路:裸的主席树

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 #define N 200010
      5 #define M N * 50
      6 
      7 int t, n, q, ans;
      8 int vis[N], arr[N];
      9 int T[N], L[M], R[M], C[M], tot;
     10 
     11 inline int build(int l, int r)
     12 {
     13     int root = tot++;
     14     C[root] = 0;
     15     if (l < r)
     16     {
     17         int mid = (l + r) >> 1;
     18         L[root] = build(l, mid);
     19         R[root] = build(mid + 1, r);
     20     }
     21     return root;
     22 }
     23 
     24 inline int update(int root, int pos, int val)
     25 {
     26     int newroot = tot++, tmp = newroot;
     27     C[newroot] = C[root] + val;
     28     int l = 1, r = n;
     29     while (l < r)
     30     {
     31         int mid = (l + r) >> 1;
     32         if (pos <= mid)
     33         {
     34             L[newroot] = tot++, R[newroot] = R[root];
     35             newroot = L[newroot], root = L[root];
     36             r = mid;
     37         }
     38         else
     39         {
     40             L[newroot] = L[root], R[newroot] = tot++;
     41             newroot = R[newroot], root = R[root];
     42             l = mid + 1;
     43         }
     44         C[newroot] = C[root] + val;
     45     }
     46     return tmp;
     47 }
     48 
     49 inline int query(int root, int pos)
     50 {
     51     int l = 1, r = n;
     52     int res = 0;
     53     while (l < r)
     54     {
     55         int mid = (l + r) >> 1;
     56         if (pos <= mid)
     57         {
     58             root = L[root];
     59             r = mid;
     60         }
     61         else
     62         {
     63             res += C[L[root]];
     64             root = R[root];
     65             l = mid + 1;
     66         }
     67     }
     68     return res + C[root];
     69 }
     70 
     71 inline int query2(int root, int k)
     72 {
     73     int l = 1, r = n;
     74     int res = 0;
     75     while (l < r)
     76     {
     77         int mid = (l + r) >> 1;
     78         if (C[L[root]] >= k)
     79         {
     80             root = L[root];
     81             r = mid;
     82         }
     83         else
     84         {
     85             k -= C[L[root]];
     86             root = R[root];
     87             l = mid + 1;
     88         }
     89     }
     90     return l;
     91 
     92 }
     93 
     94 int main()
     95 {
     96     scanf("%d", &t);
     97     for (int kase = 1; kase <= t; ++kase)
     98     {
     99         printf("Case #%d:", kase);
    100         scanf("%d%d", &n, &q); tot = 0; 
    101         for (int i = 1; i <= n; ++i) scanf("%d", arr + i);
    102         T[n + 1] = build(1, n); 
    103         memset(vis, 0, sizeof vis);
    104         for (int i = n; i >= 1; --i)
    105         {
    106             if (vis[arr[i]] == 0)
    107             {
    108                 T[i] = update(T[i + 1], i, 1);    
    109             }
    110             else
    111             {
    112                 T[i] = update(T[i + 1], vis[arr[i]], -1);
    113                 T[i] = update(T[i], i, 1);
    114             }
    115             vis[arr[i]] = i;
    116         }
    117         ans = 0;
    118         for (int i = 1, l, r; i <= q; ++i) 
    119         {
    120             scanf("%d%d", &l, &r);
    121             l = (l + ans) % n + 1;
    122             r = (r + ans) % n + 1;
    123             if (l > r) swap(l, r);
    124             if (l == r)
    125             {
    126                 printf(" %d", l);
    127                 ans = l;
    128                 continue;
    129             }
    130             int k = query(T[l], r); k = (k + 1) / 2;
    131             ans = query2(T[l], k);
    132             printf(" %d", ans);
    133         }
    134         puts("");
    135     }
    136     return 0;
    137 }
    View Code

    J - Ugly Problem

    题意:给出一个数,求这个数能够被多少个回文数相加得到,个数不能超过50,输出这些数

    思路:如果是10000 这样的数,那么就取9999  否则 就是  位数减半的前一位-1然后右半部分回文得到回文数

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 int main() {
     6     int t;
     7     char st[10000];
     8     int a[10000],b[10000],ans[100][10000];
     9     int x,y;
    10     int i,j,k,len,cnt,kase;
    11     scanf("%d",&t);
    12     kase=0;
    13     while (t--) {
    14         printf("Case #%d:
    ",++kase);
    15         scanf("%s",st);
    16         len=strlen(st);
    17         for (i=0;i<len;++i)
    18             a[len-i]=st[i]-48;
    19         x=len;
    20         cnt=0;
    21         while (x>1) {
    22             cnt++;
    23             k=x/2+1;
    24             memset(b,0,sizeof b);
    25             while (k<=x) {
    26                 if (a[k]==0) b[k]=9;
    27                 else 
    28                 {
    29                     b[k]=a[k]-1;
    30                     k++;
    31                     break;
    32                 }
    33                 k++;
    34             }
    35             while (k<=x) {
    36                 b[k]=a[k];
    37                 k++;
    38             }
    39             y=x;
    40             for (i=1;i<=x/2;++i)
    41                 b[i]=b[y-i+1];
    42             if (b[y]==0) {b[1]=9; y--;}
    43             ans[cnt][0]=y;
    44             for (i=y;i>=1;--i) {
    45                 ans[cnt][i]=b[i];
    46                 //printf("%d",b[i]);
    47                 a[i]=a[i]-b[i];
    48             }
    49             //printf("
    ");
    50             for (i=1;i<=x;++i)
    51                 if (a[i]<0) {
    52                     a[i]=a[i]+10;
    53                     a[i+1]--;
    54                 }
    55             while (a[x]==0) --x;
    56         }
    57         if (a[1]!=0) {cnt++; ans[cnt][0]=1; ans[cnt][1]=a[1];}
    58         printf("%d
    ",cnt);
    59         for (i=1;i<=cnt;++i) {
    60             for (j=ans[i][0];j>=1;--j) printf("%d",ans[i][j]);
    61             printf("
    ");
    62         }
    63     }
    64     return 0;
    65 }
    View Code

    K - Binary Indexed Tree

    留坑。

  • 相关阅读:
    当spfile文件中的参数修改错误,导致数据库无法启动问题
    oracle的shared server模式和dedicated server模式
    概述oracle的内存结构
    oracle进程简介
    TNS12516及ORA12516错误解决
    如何打补丁及升级
    关于sqlplus的简单概述
    修改参数之后数据库无法启动问题
    oracle的后台进程杀掉会有什么影响
    远程连接oracle数据库ORA12154错误
  • 原文地址:https://www.cnblogs.com/Dup4/p/9649051.html
Copyright © 2011-2022 走看看