zoukankan      html  css  js  c++  java
  • 2015ACM/ICPC亚洲区沈阳站 Solution

    A - Pattern String

    留坑。

    B - Bazinga

    题意:找一个最大的i,使得前i - 1个字符串中至少不是它的子串

    思路:暴力找,如果有一个串已经符合条件,就不用往上更新

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 510
     5 
     6 int t, n;
     7 int vis[N];
     8 string s[N];
     9 
    10 int main()
    11 {
    12     ios::sync_with_stdio(false);
    13     int t;
    14     cin >> t;
    15     for(int cas = 1; cas <= t; ++cas)
    16     {
    17         cin >> n;
    18         memset(vis, 0, sizeof vis);
    19         for(int i = 1; i <= n; ++i) cin >> s[i];
    20         int ans = -1;
    21         for(int i = 1; i <= n; ++i)
    22         {
    23             for(int j  = i + 1; j <= n; ++j)
    24             {
    25                 if(!vis[j])
    26                 {
    27                     int tmp = s[j].find(s[i]);
    28                     if(tmp == -1)
    29                     {
    30                         vis[j] = 1;
    31                         ans = max(ans, j);
    32                     }
    33                     else break;
    34                 }
    35             }
    36         }
    37         cout << "Case #" << cas << ": " << ans << endl;
    38     }
    39     return 0;
    40 }
    View Code

    C - Minimum Cut-Cut

    留坑。

    D - Pagodas

    题意:刚开始集合里有a, b 两个数,每次能从集合中选出 x + y  或者 x - y 放进集合中,并且放过的不能放,不能放的输游戏

    思路:考虑$gcd(x, y), 每次产生的新数肯定是gcd(x, y)的倍数$ 所以能放的数总数只有 gcd(x, y) 的倍数的个数

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 int gcd(int a, int b)
     6 {
     7     return b == 0 ? a : gcd(b, a % b);
     8 }
     9 
    10 int n, a, b;
    11 
    12 int main()
    13 {
    14     int t;
    15     scanf("%d", &t);
    16     for(int cas = 1; cas <= t; ++cas)
    17     {
    18         scanf("%d %d %d", &n, &a, &b);
    19         int g = gcd(a, b);
    20         int tmp = n / g;
    21         printf("Case #%d: ", cas);
    22         puts(tmp & 1 ? "Yuwgna" : "Iaka");
    23     }
    24     return 0;
    25 }
    View Code

    E - Efficient Tree

    留坑。

    F - Frogs

    题意:有n只青蛙,长度为m的环,每只青蛙固定步数往前跳,跳到一个点标记一下,求最后有多少点被标记

    思路:先将m分解因子,对于每一个arr[i]都和m求gcd,然后将gcd的倍数标记一次,代表需要统计一次它的倍数。最后遍历一边每个因子,求出它被多用几次或者少用几次的和即可。

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 #define ll long long
     6 #define N 10010
     7 
     8 ll gcd(ll a, ll b)
     9 {
    10     return b == 0 ?  a :  gcd(b, a % b);
    11 }
    12 
    13 int n, m;
    14 int vis[N], used[N];
    15 ll arr[N];
    16 vector<int>vec;
    17 
    18 int main()
    19 {
    20     int t;
    21     scanf("%d", &t);
    22     for(int cas = 1; cas <= t; ++cas)
    23     {
    24         scanf("%d %d", &n, &m);
    25         memset(vis, 0, sizeof vis);
    26         memset(used, 0, sizeof used);
    27         vec.clear();
    28         for(int i = 1; i * i <= m; ++i)
    29         {
    30             if(m % i == 0)
    31             {
    32                 vec.push_back(i);
    33                 if(i * i != m) vec.push_back(m / i);
    34             }
    35         }
    36         sort(vec.begin(), vec.end());
    37         int tot = vec.size();
    38         tot--;
    39         for(int i = 1; i <= n; ++i)
    40         {
    41             scanf("%lld", arr + i);
    42             ll x = gcd(arr[i], m);
    43             for(int j = 0; j < tot; ++j)
    44             {
    45                 if(vec[j] % x == 0) vis[j] = 1;
    46             }
    47         }
    48         ll ans = 0;
    49         for(int i = 0; i < tot; ++i)
    50         {
    51             if(vis[i] != used[i])
    52             {
    53                 ll tmp = (m - 1) / vec[i];
    54                 ans += tmp * (tmp + 1) / 2 * vec[i] * (vis[i] - used[i]);
    55                 for(int j = i + 1; j < tot; ++j)
    56                 {
    57                     if(vec[j] % vec[i] == 0) 
    58                     {
    59                         used[j] += vis[i] - used[i];
    60                     }                        
    61                 }
    62             }
    63         }
    64         printf("Case #%d: %lld
    ", cas, ans);
    65     }
    66     return 0;
    67 }
    View Code

    G - Game of Flying Circus

    题意:翻译啊翻译

    思路:分类讨论

    1)在1-2相遇   即v1=v2  输出Yes

    2)在2-3相遇,利用二分计算出相遇点,算一下到4的时间,判断

    3)在3-4相遇,利用二分计算出相遇点,算一下到1的时间,判断

    4)一定No

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 const double eps = 1e-8;
     6 
     7 double T, v1, v2;
     8 
     9 int sgn(double x)
    10 {
    11     if(fabs(x) < eps) return 0;
    12     else return x > 0 ? 1 : -1;
    13 }
    14 
    15 int main()
    16 {
    17     int t;
    18     scanf("%d", &t);
    19     for(int cas = 1; cas <= t; ++cas)
    20     {
    21         scanf("%lf %lf %lf", &T, &v1, &v2);
    22         printf("Case #%d: ", cas);
    23         if(sgn(v1 - v2) == 0) puts("Yes");
    24         else if(sgn(2 * v1 * v1 - v2 * v2) > 0)//2-3
    25         {
    26             double l = 0, r = 300.0;
    27             while(r - l > eps)
    28             {
    29                 double mid = (l + r) / 2.0;
    30                 double dis1 = sqrt(mid * mid + 300.0 * 300.0);
    31                 double t1 = dis1 / v1;
    32                 double dis2 = mid + 300.0;
    33                 double t2 = dis2 / v2;
    34                 if(sgn(t1 - t2) > 0)
    35                 {
    36                     l = mid;
    37                 }
    38                 else 
    39                 {
    40                     r = mid;
    41                 }
    42             }
    43             double x = (l + r) / 2.0;
    44             double dis1 = x + 600.0;
    45             double t1 = dis1 / v1;
    46             double dis2 = 600.0 - x;
    47             double t2 = dis2 / v2 + T;
    48             puts(sgn(t1 - t2) <= 0 ? "Yes" : "No");
    49         }
    50         else if(sgn(3 * v1 - v2) > 0)//3-4
    51         {
    52             double l = 0, r = 300.0;
    53             while(r - l > eps)
    54             {
    55                 double mid = (l + r) / 2.0;
    56                 double dis1 = sqrt(mid * mid + 300.0 * 300.0);
    57                 double t1 = dis1 / v1;
    58                 double dis2 = 900.0 - mid;
    59                 double t2 = dis2 / v2;
    60                 if(sgn(t1 - t2) > 0)
    61                 {
    62                     r = mid;
    63                 }
    64                 else 
    65                 {
    66                     l = mid;
    67                 }
    68             }
    69             double y = (l + r) / 2.0;
    70             double dis1 = sqrt((300.0 - y) * (300.0 - y) + 300.0 * 300.0) + 900.0;
    71             double t1 = dis1 / v1;
    72             double dis2 = y + 300.0;
    73             double t2 = dis2 / v2 + T;
    74             puts(sgn(t1 - t2) <= 0 ? "Yes" : "No");
    75         }
    76         else puts("No");
    77     }
    78     return 0;
    79 }
    View Code

    H - Chessboard

    留坑。

    I - Triple

    题意:二元组$A<a, b>$ 三元组 $B<c, d, e> A * B = {<a, c, d> | <a, b> in A , <c, d, e> in B and b = e}$ 求有多少集合满足TOP(C)

    思路:枚举B,对于每个B,我们考虑符合条件的最高的a, 因为有多个a,那么小的a肯定不会放到集合里面,

    对于最大的a,我们判断二维BIT中右下角有的最大值,是否大于它本身,不是的话它就应该放进TOP(C) 

    要多考虑一下当前的(c, d) 有多个点的情况

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 #define N 100010
      5 #define pii pair <int, int>
      6 #define ll long long
      7 
      8 int t, n, m;
      9 struct A
     10 {
     11     int a, b;
     12     void scan()
     13     {
     14         scanf("%d%d", &a, &b);
     15     }
     16     bool operator < (const A &r) const
     17     {
     18         return b == r.b ? a < r.a : b < r.b;
     19     }
     20 }a[N];
     21 
     22 struct B
     23 {
     24     int c, d, e;
     25     void scan()
     26     {
     27         scanf("%d%d%d", &c, &d, &e);
     28     }
     29 }b[N];
     30 
     31 pii pos[N];  
     32 
     33 struct BIT
     34 {
     35     int a[1010][1010];
     36 
     37     void Init()
     38     {
     39         memset(a, 0, sizeof a);
     40     }
     41 
     42     void update(int x, int y, int val)
     43     {
     44         for (int i = x; i; i -= i & -i)
     45             for (int j = y; j; j -= j & -j)
     46                 a[i][j] = max(a[i][j], val);
     47     }
     48 
     49     int query(int x, int y)
     50     {
     51         int res = 0;
     52         for (int i = x; i < 1010; i += i & -i)
     53             for (int j = y; j < 1010; j += j & -j)
     54                 res = max(res, a[i][j]);
     55         return res;
     56     }
     57 }bit; 
     58 
     59 int main()
     60 {
     61     scanf("%d", &t);
     62     for (int kase = 1; kase <= t; ++kase)
     63     {
     64         printf("Case #%d: ", kase); 
     65         scanf("%d%d", &n, &m); 
     66         for (int i = 1; i <= n; ++i) a[i].scan(); 
     67         for (int i = 1; i <= m; ++i) b[i].scan(); 
     68         sort(a + 1, a + 1 + n);     
     69         memset(pos, 0, sizeof pos); 
     70         for (int i = n; i >= 1; --i)
     71         {
     72             int b = a[i].b;
     73             if (!pos[b].first)
     74             {
     75                 pos[b].first = a[i].a, ++pos[b].second; 
     76                 continue;    
     77             }
     78             if (i != n) 
     79             {
     80                 if (b == a[i + 1].b && a[i].a == pos[b].first) 
     81                     ++pos[b].second; 
     82             }
     83         }
     84         bit.Init(); 
     85         for (int i = 1; i <= m; ++i) 
     86         {
     87             if (pos[b[i].e].first == 0) continue;
     88             bit.update(b[i].c, b[i].d, pos[b[i].e].first);
     89         }
     90         ll res = 0; 
     91         for (int i = 1; i <= m; ++i)
     92         {
     93             int x = b[i].c, y = b[i].d;
     94             if(!pos[b[i].e].first) continue;
     95             int Max = max(bit.query(x, y + 1), bit.query(x + 1, y));
     96             bool flag = true; 
     97             if (Max >= pos[b[i].e].first) flag = false;
     98             Max = bit.query(x, y); if (Max != pos[b[i].e].first) flag = false;
     99             if (flag) res += pos[b[i].e].second;
    100         }
    101         printf("%lld
    ", res);
    102     }
    103     return 0;
    104 }
    View Code

    J - John's Fences

    留坑。

    K - Kykneion asma

    留坑。

    L - Number Link

    留坑。

    M - Meeting

    题意:有多个集合,集合里两个点的距离都是$t-i$ 1 和 n  要到一个地方汇合,使得最大距离最小,求汇合点

    思路:考虑暴力连边的边数最大有${sum_{i = 1}^{i = m} S_i} ^2$ 没法解决

    考虑将一个集合里所有点向另一个点连权值为$t_i$的边,再从这个点向集合里所有点连权值为0的边

    再对1和n分别跑最短路,枚举中间点,更新答案

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 #define N 2000010
      5 #define ll long long
      6 #define INFLL 0x3f3f3f3f3f3f3f3f
      7 
      8 int t, n, m;
      9 int arr[N];
     10 
     11 struct Edge
     12 {
     13     int to, nx; ll w;
     14     Edge() {}
     15     Edge(int to, int nx, ll w) : to(to), nx(nx), w(w) {}
     16 }edge[N << 1]; 
     17 
     18 int head[N], pos;
     19 
     20 void Init()
     21 {
     22     memset(head, -1, sizeof head);
     23     pos = 0;
     24 }
     25 
     26 void addedge(int u, int v, int w)
     27 {
     28     edge[++pos] = Edge(v, head[u], w); head[u] = pos;
     29 }
     30 
     31 struct node
     32 {
     33     int u; ll w;
     34     node () {}
     35     node (int u, ll w) : u(u), w(w) {}
     36     bool operator < (const node &r) const
     37     {
     38         return w > r.w;
     39     }
     40 };
     41 
     42 ll dist[2][N];
     43 bool used[N];
     44 
     45 void Dijkstra(int st, int id)
     46 {
     47     for (int i = 1; i <= n + m; ++i) dist[id][i] = INFLL, used[i] = 0;
     48     priority_queue <node> q;
     49     q.emplace(st, 0);
     50     dist[id][st] = 0;
     51     while (!q.empty())
     52     {
     53         int u = q.top().u; q.pop();
     54         if (used[u]) continue;
     55         used[u] = 1;
     56         for (int it = head[u]; ~it; it = edge[it].nx)
     57         {
     58             int v = edge[it].to;
     59             if (!used[v] && dist[id][v] > dist[id][u] + edge[it].w)
     60             {
     61                 dist[id][v] = dist[id][u] + edge[it].w;
     62                 q.emplace(v, dist[id][v]);
     63             }
     64         }
     65     }
     66 }
     67 
     68 
     69 int main()
     70 {
     71     scanf("%d", &t);
     72     for (int kase = 1; kase <= t; ++kase)
     73     {
     74         printf("Case #%d: ", kase);
     75         scanf("%d%d", &n, &m);
     76         Init();
     77         for (int i = 1, tot, w; i <= m; ++i)
     78         {
     79             scanf("%d%d", &w, &tot);
     80             for (int j = 1; j <= tot; ++j) scanf("%d", arr + j);
     81             for (int j = 1; j <= tot; ++j) addedge(arr[j], i + n, w);
     82             for (int j = 1; j <= tot; ++j) addedge(i + n, arr[j], 0); 
     83         }    
     84         Dijkstra(1, 0);
     85         Dijkstra(n, 1);
     86         vector <int> v;
     87         ll Min = INFLL;
     88 //        for (int i = 1; i <= n; ++i) cout << dist[0][i] << " " << dist[1][i] << endl;
     89         for (int i = 1; i <= n; ++i) Min = min(Min, max(dist[0][i], dist[1][i]));
     90         if (Min == INFLL) puts("Evil John");
     91         else
     92         {
     93             for (int i = 1; i <= n; ++i) if (max(dist[0][i], dist[1][i]) == Min)
     94                 v.push_back(i);
     95             printf("%lld
    ", Min);
     96             for (int i = 0, len = v.size(); i < len; ++i) printf("%d%c", v[i], " 
    "[i == len - 1]);
     97         }
     98     }
     99     return 0;
    100 }
    View Code

    C=AB={a,c,da,bA, c,d,eB and b=e}

  • 相关阅读:
    [置顶] Docker学习总结(3)——Docker实战之入门以及Dockerfile(三)
    [置顶] Docker学习总结(2)——Docker实战之入门以及Dockerfile(二)
    Vue-Router中History模式【华为云分享】
    Linux系统通过FTP进行文档基本操作【华为云分享】
    窥探日志的秘密【华为云分享】
    弹性负载均衡:负载无限,均衡有道【华为云分享】
    不给糖果就捣乱,用Python绘制有趣的万圣节南瓜怪【华为云分享】
    机器学习笔记(八)---- 神经网络【华为云分享】
    还在为运维烦恼?体验云上运维服务,提意见赢好礼!【华为云分享】
    Vue+ElementUI项目使用webpack输出MPA【华为云分享】
  • 原文地址:https://www.cnblogs.com/Dup4/p/9783359.html
Copyright © 2011-2022 走看看