• CCPC-Wannafly Winter Camp Day2 (Div2, onsite)


    Class


    $A_i = a cdot i \% n$

    有 $A_i = k cdot gcd(a, n)$

    证明:

    $A_0 = 0, A_x = x cdot a - y cdot n$

    $令 d = gcd(a, n)$

    $A_x \% d = (x cdot a \% d - y cdot n \% d) \% d = 0$ 得证

    循环节为$frac {n}{gcd(a, n)}$

    Replay


    Dup4:

    • 自闭了,啥都不会,想开一道无人做的字符串,喵喵喵?
    • 总是陷入思维的泥浆,爬不出来,T那么大,怎么就想不到预处理呢

     X:

    • 成功晋升码农
    • 第三次忘记预处理是个啥,最后全靠队友一波rush
    • 日常开局血崩,这口锅必须要背

    Solution


     


    A: Erase Numbers II

    思路:

    $n^2 暴力 注意最大的那项会爆 long; long  但不会爆 unsigned ;long ;long$

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 typedef unsigned long long ull;
     6 const int maxn = 1e5 + 10;
     7 
     8 int n;
     9 ull arr[maxn];
    10 ull len[maxn];
    11 
    12 int main()
    13 {
    14     int t;
    15     scanf("%d", &t);
    16     for(int cas = 1; cas <= t; ++cas)
    17     {
    18         printf("Case #%d: ", cas);
    19         scanf("%d", &n);
    20         for(int i = 1; i <= n; ++i)
    21         {
    22             scanf("%llu", arr + i);
    23             len[i] = 1;
    24             ull x = arr[i];
    25             while(x)
    26             {
    27                 len[i] *= 10;
    28                 x /= 10;
    29             }
    30         }
    31         ull ans = 0;
    32         for(int i = 1; i <= n; ++i)
    33         {
    34             for(int j = i + 1; j <= n; ++j)
    35             {
    36                 ans = max(ans, arr[i] * len[j] + arr[j]);
    37             }
    38         }
    39         printf("%llu
    ", ans);
    40     }
    41     return 0;
    42 }
    View Code

    B: Erase Numbers I

    思路:

    $将删除两个数当做两次操作$

    $每次操作删除剩余串中长度最小$

    $先O(n)扫一遍,如果找到一个长度最小并且字典序小于后一位的,即可直接上出,并且保证了最优$

    $如果第一遍扫没找到合适的, 就从后往前找到第一个长度最小的删除$

    $做两遍即可$

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 const int INF = 0x3f3f3f3f;
     6 const int maxn = 1e4 + 10;
     7 
     8 struct node{
     9     char str[20];
    10     int len;
    11     int flag;
    12 }arr[maxn];
    13 
    14 int n;
    15 
    16 int main()
    17 {
    18     int t;
    19     scanf("%d", &t);
    20     for(int cas = 1; cas <= t; ++cas)
    21     {
    22         printf("Case #%d: ", cas);
    23         scanf("%d", &n);
    24         for(int i = 1; i <= n; ++i)
    25         {
    26             scanf("%s", arr[i].str);
    27             arr[i].len = strlen(arr[i].str);
    28             arr[i].flag = 0;
    29         }
    30         int pos1 = -1, pos2 = -1;
    31         int Min = INF;
    32         for(int i = 1; i <= n; ++i) if(!arr[i].flag) Min = min(Min, arr[i].len);
    33         for(int i = 1; i <= n; ++i)
    34         {
    35             if(arr[i].flag) continue;
    36             if(Min != arr[i].len) continue;
    37             int j  = i + 1;
    38             while(arr[j].flag && j <= n) ++j;
    39             if(j <= n)
    40             {
    41                 if(strcmp(arr[i].str, arr[j].str) < 0)
    42                 {
    43                     pos1 = i;
    44                     arr[i].flag = 1;
    45                     break;
    46                 }
    47             }
    48         }
    49         if(pos1 == -1)
    50         {
    51             for(int i = n; i >= 1; --i) 
    52             {
    53                 if(arr[i].flag) continue;
    54                 if(arr[i].len == Min)
    55                 {
    56                     arr[i].flag = 1;
    57                     pos1 = i;
    58                     break;
    59                 }
    60             }
    61         }
    62         Min = INF;
    63         for(int i = 1; i <= n; ++i) if(!arr[i].flag) Min = min(Min, arr[i].len);
    64         for(int i = 1; i <= n; ++i)
    65         {
    66             if(arr[i].flag) continue;
    67             if(Min != arr[i].len) continue;
    68             int j = i + 1;
    69             while(arr[j].flag && j <= n) ++j;
    70             if(j <= n)
    71             {
    72                 if(strcmp(arr[i].str, arr[j].str) < 0)
    73                 {
    74                     pos2 = i;
    75                     arr[i].flag = 1;
    76                     break;
    77                 }
    78             }
    79         }
    80         if(pos2 == -1)
    81         {
    82             for(int i = n; i >= 1; --i)
    83             {
    84                 if(arr[i].flag) continue;
    85                 if(arr[i].len == Min)
    86                 {
    87                     arr[i].flag = 1;
    88                     pos2 = i;
    89                     break;
    90                 }
    91             }
    92         }
    93         for(int i = 1; i <= n; ++i) if(!arr[i].flag) printf("%s", arr[i].str);
    94         puts("");
    95     }
    96     return 0;
    97 }
    View Code

    H: Cosmic Cleaner

    思路:

    $球缺体积$

    $用一个平面截去一个球所得部分叫球缺$

    $球缺面积 = 2 cdot pi h$

    $球缺体积 = pi cdot h^2 cdot (R - frac{h}{3})$

    $球缺质心:匀质球缺的质心位于它的中轴线上,并且与底面的距离为$

    $C = frac{(4cdot R - h) cdot h}{12 cdot R - 4 cdot h} = frac{(d^2 + 2cdot h^2) cdot h}{3cdot d^2 + 4cdot h^2}$

    $其中,h为球缺的高,R为大圆半径,d为球缺的底面直径$

    $然后分分类 搞一搞,就好了$

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 const double eps = 1e-8;
     6 const double PI = acos(-1.0);
     7 const int maxn = 1e2 + 10;
     8 
     9 int sgn(double x)
    10 {
    11     if(fabs(x) < eps) return 0;
    12     else return x > 0 ? 1 : -1;
    13 }
    14 
    15 struct node{
    16     double x, y, z, r;
    17     node(){}
    18     node(double x, double y, double z, double r): x(x), y(y), z(z), r(r){}
    19 }O, P[maxn];
    20 
    21 double getdis(node p1, node p2)
    22 {
    23     double res = (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y) + (p1.z - p2.z) * (p1.z - p2.z);
    24     res = sqrt(res);
    25     return res;
    26 }
    27 
    28 int n;
    29 
    30 int main()
    31 {
    32     int t;
    33     scanf("%d", &t);
    34     for(int cas = 1; cas <= t; ++cas)
    35     {
    36         printf("Case #%d: ", cas);
    37         scanf("%d", &n);
    38         for(int i = 1; i <= n; ++i)
    39         {
    40             scanf("%lf %lf %lf %lf", &P[i].x, &P[i].y, &P[i].z, &P[i].r);
    41         }
    42         scanf("%lf %lf %lf %lf", &O.x, &O.y, &O.z, &O.r);
    43         double ans = 0;
    44         for(int i = 1; i <= n; ++i)
    45         {
    46             double dis = getdis(O, P[i]);
    47             double tmp = dis - O.r - P[i].r;
    48             //out
    49             if(sgn(tmp) > 0) 
    50             {
    51                 continue;
    52             }    
    53 
    54             //in
    55             if(sgn(dis + P[i].r - O.r) <= 0)
    56             {
    57                 double tmp1 = 4.0 / 3.0 * PI * P[i].r * P[i].r * P[i].r;
    58                 ans += tmp1;
    59                 continue;
    60             }
    61 
    62             //part1
    63             double r1 = O.r, r2 = P[i].r;
    64 
    65             double r0 = (r1 * r1 + dis * dis - r2 * r2) / (2.0 * dis);
    66             double h1 = r1 - r0;
    67 
    68                ans += PI * h1 * h1 * (r1 - h1 / 3.0);    
    69             
    70             //part2
    71             r0 = (r2 * r2 + dis * dis - r1 * r1) / (2.0 * dis);
    72             double h2 = r2 - r0;
    73             ans += PI * h2 * h2 * (r2 - h2 / 3.0);
    74         }
    75         printf("%.10f
    ", ans);
    76     }
    77     return 0;
    78 }
    View Code

    K: Sticks

    思路:

    将$l_i排序,接着n^3处理出合法的三角形关系,然后枚举三角形关系$

    $注意不要重复枚举,但是暴力枚举常数还是太大$

    $考虑一条剪枝,如果有一个三角关系,令其为a_1, a_2, a_3$

    $如果存在 a_x >= a_3 和 a_1 以及 a_2 也同样满足大小关系,那么这个三角关系不用枚举$

    $因为我们是从小到大枚举,在二三层循环当中枚举到的点的长度肯定比第一层的要大$

    $那么对于a_x >= a_3  将a_x留在后面的三角关系中会使得答案更优$

    然后就过了..

    但实际上有一种更为科学的?方法

    考虑合法的不重复的四对三角关系只有$frac {C_{12}^3 cdot C_{9}^3 cdot C_6^3 }{4!}$

    只有$15400 如果能够预处理出来,再暴力枚举的时间复杂度是对的$

    考虑如何预处理

    显然有个$O(220^4)的方法$

    那么我们考虑能否优化掉第四维的$220$

    $其实前三个三角关系确定了,第四个自然确定了,但是我们需要去重啊$

    先考虑不重不漏的枚举三角关系 从小到大,并且每一个三角关系都有唯一编号

    $用 Hash[][][] 进行Hash$

    这样就可以$O(1)得到剩下的那个三角关系的编号,考虑编号和前三个三角关系编号的大小$

    如果小了,那么肯定重复了

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 #define N 15
      5 int t, l[N], vis[N];
      6 struct node
      7 {
      8     int x, y, z;
      9     node () {}
     10     node (int x, int y, int z) : x(x), y(y), z(z) {}
     11 }; vector <node> v;
     12 vector <int> res;
     13 int Stack[100010], top;
     14 
     15 bool ok(int x, int y, int z)
     16 {
     17     if (x + y > z && x + z > y && y + z > x) return 1;
     18     return 0;
     19 }
     20 
     21 bool used(node a)
     22 {
     23     if (!vis[a.x] && !vis[a.y] && !vis[a.z]) return 0;
     24     return 1;
     25 }
     26 
     27 void work(int i)
     28 {
     29     Stack[++top] = v[i].x;
     30     Stack[++top] = v[i].y;
     31     Stack[++top] = v[i].z;
     32     vis[v[i].x] = 1;
     33     vis[v[i].y] = 1;
     34     vis[v[i].z] = 1;
     35 }
     36 
     37 void clear(int i)
     38 {
     39     top -= 3;
     40     vis[v[i].x] = 0;
     41     vis[v[i].y] = 0;
     42     vis[v[i].z] = 0;
     43 }
     44 
     45 void add()
     46 {
     47     if (top > res.size())
     48     {
     49         res.clear();
     50         for (int o = 1; o <= top; ++o) res.push_back(Stack[o]);
     51     }
     52 }
     53 
     54 void solve()
     55 {
     56     int m = v.size();
     57     for (int i = 0; i < m; ++i)  if (i == 0 || !(v[i].x == v[i - 1].x && v[i].y == v[i - 1].y))
     58     {
     59         work(i); add();
     60         for (int j = i + 1; j < m; ++j) if (!used(v[j]))            
     61         {
     62             work(j); add(); 
     63             for (int k = j + 1; k < m; ++k) if (!used(v[k])) 
     64             {
     65                 work(k); add();
     66                 int a[3] = {0}, cnt = 0; 
     67                 for (int o = 1; o <= 12; ++o) if (!vis[o])
     68                     a[cnt++] = o;
     69                 if (ok(l[a[0]], l[a[1]], l[a[2]]))
     70                 {
     71                     for (int o = 0; o < 3; ++o) Stack[++top] = a[o];
     72                     add();
     73                     return;
     74                 }
     75                 clear(k);
     76             }
     77             clear(j);
     78         }
     79         clear(i);
     80     }
     81 }
     82 
     83 int main()
     84 {
     85     scanf("%d", &t);
     86     for (int kase = 1; kase <= t; ++kase)
     87     {
     88         printf("Case #%d: ", kase); top = 0; res.clear();
     89         memset(vis, 0, sizeof vis);
     90         for (int i = 1; i <= 12; ++i) scanf("%d", l + i);
     91         sort(l + 1, l + 13);
     92         v.clear();
     93         for (int i = 1; i <= 12; ++i) for (int j = i + 1; j <= 12; ++j) for (int k = j + 1; k <= 12; ++k) if (ok(l[i], l[j], l[k]))
     94             v.push_back(node(i, j, k));
     95         solve();
     96         int k = res.size() / 3;
     97         printf("%d
    ", k);
     98         for (int i = 0, len = res.size(); i < len; ++i) printf("%d%c", l[res[i]], " 
    "[(i + 1) % 3 == 0]);
     99     }
    100     return 0;
    101 }
    View Code
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 15
     5 #define M 200100
     6 int t, n, l[N], vis[N];
     7 
     8 struct node
     9 {    
    10     int a[3];
    11     node () {}
    12     node (int x, int y, int z) 
    13     {
    14         a[0] = x;
    15         a[1] = y;
    16         a[2] = z;
    17     }
    18     bool ok()
    19     {
    20         if (l[a[0]] + l[a[1]] > l[a[2]] && l[a[0]] + l[a[2]] > l[a[1]] && l[a[1]] + l[a[2]] > l[a[0]]) return 1;
    21         return 0;
    22     }
    23     void out()
    24     {
    25         for (int i = 0; i < 3; ++i) printf("%d%c", l[a[i]], " 
    "[i == 2]);
    26     }
    27 }; vector <node> vec;
    28 node que[M][5];
    29 node Stack[110]; int top;
    30 int Hash[15][15][15]; 
    31 
    32 void used(node x) { for (int i = 0; i < 3; ++i) vis[x.a[i]] = 1; }
    33 void clear(node x) { for (int i = 0; i < 3; ++i) vis[x.a[i]] = 0; --top; } 
    34 bool notused(node x) { for (int i = 0; i < 3; ++i) if (vis[x.a[i]]) return false; return true; }
    35 
    36 void init()
    37 {
    38     int m = 0;
    39     for (int i = 1; i <= 12; ++i) for (int j = i + 1; j <= 12; ++j) for (int k = j + 1; k <= 12; ++k)
    40     {
    41         vec.push_back(node(i, j, k));
    42         Hash[i][j][k] = m;
    43         ++m;
    44     }
    45     n = 0; top = 0;  
    46     for (int i = 0; i < m; ++i) 
    47     {
    48         Stack[++top] = vec[i];
    49         used(vec[i]);
    50         for (int j = i + 1; j < m; ++j) if (notused(vec[j]))
    51         {
    52             Stack[++top] = vec[j];
    53             used(vec[j]);
    54             for (int k = j + 1; k < m; ++k) if (notused(vec[k])) 
    55             {
    56                 Stack[++top] = vec[k];
    57                 used(vec[k]);
    58                 node tmp; int cnt = 0;
    59                 for (int o = 1; o <= 12; ++o) if (!vis[o]) 
    60                     tmp.a[cnt++] = o; 
    61                 if (Hash[tmp.a[0]][tmp.a[1]][tmp.a[2]] > k)
    62                 {    
    63                     Stack[++top] = tmp;
    64                     ++n;
    65                     for (int o = 1; o <= top; ++o) que[n][o] = Stack[o];
    66                     --top;
    67                 }
    68                 clear(vec[k]); 
    69             }
    70             clear(vec[j]);
    71         }
    72         clear(vec[i]);
    73     }
    74 }
    75 
    76 int main()
    77 {
    78     init();
    79     scanf("%d", &t);
    80     for (int kase = 1; kase <= t; ++kase)
    81     {
    82         printf("Case #%d: ", kase);
    83         for (int i = 1; i <= 12; ++i) scanf("%d", l + i);
    84         vector <node> res, tmp;
    85         for (int i = 1; i <= n; ++i) 
    86         {
    87             tmp.clear();
    88             for (int j = 1; j <= 4; ++j) if (que[i][j].ok())
    89                 tmp.push_back(que[i][j]);
    90             if (tmp.size() > res.size()) res = tmp;
    91             if (res.size() == 4) break;
    92         }
    93         int k = res.size();
    94         printf("%d
    ", k);
    95         for (int i = 0; i < k; ++i) res[i].out();
    96     }
    97     return 0;
    98 }
    View Code
  • 相关阅读:
    Apache mod_rewrite
    vim 常用设置
    ssh 和 scp 命令访问非默认22端口。
    gulp常用插件
    gulp+Babel 搭建ES6环境
    ES6类与模块
    Autoprefixer处理CSS3属性前缀
    js模块方案
    ES6转码器babel的使用
    window.history.pushState与ajax实现无刷新更新页面url
  • 原文地址:https://www.cnblogs.com/Dup4/p/10301355.html
Copyright © 2020-2023  润新知