zoukankan      html  css  js  c++  java
  • 2017-2018 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) Solution

    A - Odd Palindrome

    水。

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 #define N 110
     6 
     7 char s[N];
     8 
     9 inline bool work()
    10 {
    11     int len = strlen(s);
    12     for (int i = 1; i < len; ++i)
    13     {
    14         if (s[i] == s[i - 1]) return false;
    15     }
    16     return true;
    17 }
    18 
    19 int main()
    20 {
    21     while (scanf("%s", s) != EOF)
    22     {
    23         puts(work() ? "Odd." : "Or not.");
    24     }
    25     return 0;
    26 }
    View Code

    B - Enlarging Enthusiasm

    留坑。

    C - Fear Factoring

    题意:定义$F(n)$ 为 n的约数和  求 $S = sum_{a <= n <= b}  F(n)$

    思路:对于1-$sqrt(b)$内的因数可以进行枚举。对于大于$sqrt(b)$的因数,在枚举1-sqrt(b)的因数i的时候,a-b内的(a-1)/i, b/i是一段连续的数,通过求和公式即可得到

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 typedef long long ll;
     6 
     7 ll a,b;
     8 
     9 int main()
    10 {
    11     while(~scanf("%lld %lld", &a, &b))
    12     {
    13         if(a > b) swap(a, b);
    14         ll tmp = sqrt(b);
    15         ll ans = 0;
    16         for(ll i = 1; i <= tmp; ++i)
    17         {
    18             ans += i * (b / i - (a - 1) / i);
    19             ll tmp1 = max(tmp, (a - 1) / i);
    20             ll tmp2 = max(tmp, b / i);
    21             ans += (tmp2 - tmp1) * (tmp1 + tmp2 + 1) / 2;
    22         }
    23         printf("%lld
    ", ans);
    24     }
    25     return 0;
    26 }
    View Code

    D - Rainbow Roads

    题意:彩虹:一条路径当中,相邻的两条边,权值都不同     好点:以某个点为端点的所有简单路径当中,都是彩虹。 求一棵树当中有多少个好点

    思路:两种情况

    1° DFS下去碰到相邻的两条边,那么这两条边的最上面的那个点上面的其他所有点都不是好点,这两条边最下面那个点的子树的所有点,都不是好点

    2°以某个点为根的子树中,有两个直系儿子的边权相同,那么这两个儿子的子树的所有点都不是好点

    DFS序  区间标记

      1 #include<bits/stdc++.h>
      2 
      3 using namespace std;
      4 
      5 #define N 50010
      6 
      7 struct node{
      8     int v;
      9     int c;
     10     inline node(){}
     11     inline node(int v,int c) :v(v),c(c){}
     12     inline bool operator < (const node &b) const
     13     {
     14         return c < b.c;
     15     }
     16 };
     17 
     18 int n;
     19 vector<node>G[N];
     20 int fa[N];
     21 int son[N];
     22 int ord[N];
     23 int dro[N];
     24 int arr[N];
     25 int cnt;
     26 
     27 inline void Init()
     28 {
     29     cnt = 0;
     30     memset(arr, 0, sizeof arr);
     31     for(int i = 1; i <= n; ++i)
     32     {
     33         G[i].clear();
     34     }
     35 }
     36 
     37 inline void DFS(int u,int pre)
     38 {
     39     fa[u] = pre;
     40     ord[u] = ++cnt;
     41     dro[cnt] = u;
     42     son[u] = 1;
     43     for(auto it : G[u])
     44     {
     45         int v = it.v;
     46         if(v == pre) continue;
     47         DFS(v, u);
     48         son[u] += son[v];
     49     }
     50 }
     51 
     52 int main()
     53 {
     54     while(~scanf("%d", &n))
     55     {
     56         Init();
     57         for(int i = 1; i < n; ++i)
     58         {
     59             int u, v, c;
     60             scanf("%d %d %d", &u, &v, &c);
     61             G[u].push_back(node(v, c));
     62             G[v].push_back(node(u, c));
     63         }
     64         DFS(1, -1);
     65         for(int i = 1; i <= n; ++i)
     66         {
     67             sort(G[i].begin(), G[i].end());
     68             int len = G[i].size();
     69             int it = 0;
     70             for(int j = it; j < len; j = it)
     71             {
     72                 ++it;
     73                 while(it < len && G[i][it].c == G[i][j].c)
     74                 {
     75                     ++it;
     76                 }
     77                 if(it > j + 1)
     78                 {
     79                     for(int k = j; k < it; ++k)
     80                     {
     81                         int v = G[i][k].v;
     82                         if(v == fa[i])
     83                         {
     84                             ++arr[ord[1]];
     85                             --arr[ord[i]];
     86                             ++arr[ord[i] + son[i]];
     87                         }
     88                         else
     89                         {
     90                             ++arr[ord[v]];
     91                             --arr[ord[v] + son[v]];
     92                         }
     93                     }
     94                 }
     95             }
     96         }
     97         for(int i = 1; i <= n; ++i)
     98         {
     99             arr[i] += arr[i - 1];
    100         }
    101         vector<int>vec;
    102         for(int i = 1; i <= n; ++i)
    103         {
    104             if(arr[i] == 0)
    105             {
    106                 vec.push_back(dro[i]);
    107             }
    108         }
    109         int len = vec.size();
    110         sort(vec.begin(), vec.end());
    111         printf("%d
    ", len);
    112         for(int i = 0; i < len; ++i)
    113         {
    114             printf("%d
    ",vec[i]);
    115         }
    116     }
    117     return 0;
    118 }
    View Code

    E - Straight Shot

    题意:一个机器人,给定初始速度,问从(0,0)到(0,x)。在这段路程上存在沿着y轴方向滑动的部分街道

    思路:对v进行正交分解后,很容易发现vy=$sum_{l <= i <= n }  (r - l) * vi$ 从而得到了vy,在进行计算vx,从而得到时间。

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 double x, v, vy;
     6 double l, r, vi, tmp;
     7 
     8 int n;
     9 
    10 int main()
    11 {
    12     while(~scanf("%d %lf %lf", &n, &x, &v))
    13     {
    14         tmp = 0;
    15         for(int i = 1; i <= n; ++i)
    16         {
    17             scanf("%lf %lf %lf", &l, &r, &vi);
    18             tmp += (r - l) * vi;
    19         }
    20         vy = tmp / x;
    21         if(fabs(vy) > v)
    22         {
    23             puts("Too hard");
    24         }
    25         else
    26         {
    27             double vx = sqrt(v * v - vy * vy);
    28             double ans = x / vx;
    29             printf("%.3f
    ", ans);
    30         }
    31     }
    32     return 0;
    33 }
    View Code

    F - Distinct Distances

    留坑。

    G - Security Badge

    留坑。

    H - Avoiding Airports

    留坑。

    I - Long Long Strings

    题意:有两个长度为$10_10$的DNA序列,刚开始相同,有两类操作,一种是添加,一种是删除,求两个DNA序列经过一系列操作后是否相同

    思路:维护两个东西,一个是新添加的坐标,一个是在原序列中删除的坐标

    新添加的话,那么在它之前添加的坐标大于等于它的都要后移一位

    删除的话,如果是删除的新添加的,就直接删除,要注意新添加的坐标在它后面的都要前移一位

    如果是在原序列中删除,要考虑删除的坐标是原来在它之前新添加的,要后移一位,还有在它之前的删除的都要加上

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define ll long long
     5 
     6 typedef pair <ll, char> plc;
     7 
     8 vector <ll> Del[2];
     9 vector <plc> Ins[2];
    10 char s[10]; ll num; char c; 
    11 
    12 inline bool Dell(int vis, ll num) 
    13 {
    14     for (int i = 0, len = Ins[vis].size(); i < len; ++i) if (Ins[vis][i].first == num)
    15     {
    16         Ins[vis].erase(Ins[vis].begin() + i); 
    17         for (auto &it : Ins[vis]) if (it.first >= num)
    18             --it.first;
    19         return true;
    20     }
    21     return false;  
    22 } 
    23 
    24 inline void Delll(int vis)  
    25 {
    26     ll tmp = num; 
    27     for (auto &it : Ins[vis]) 
    28     {
    29         if (num >= it.first) 
    30             --tmp; 
    31         else
    32             --it.first;  
    33     }
    34     for (auto it : Del[vis])
    35     {
    36         if (it <= tmp)  
    37             ++tmp;    
    38         else
    39             break;
    40     }
    41     num = tmp; 
    42 }
    43 
    44 inline void work(int vis) 
    45 {
    46     Ins[vis].clear(); Del[vis].clear(); 
    47     while (scanf("%s", s), s[0] != 'E') 
    48     {
    49         scanf("%lld", &num);
    50         if (s[0] == 'I')
    51         {
    52             scanf(" %c", &c);
    53             for (auto &it : Ins[vis]) if (it.first >= num)
    54                 ++it.first;
    55             Ins[vis].emplace_back(num, c);
    56             for (int len = Ins[vis].size(), i = len - 1; i >= 1; --i) if (Ins[vis][i].first < Ins[vis][i - 1].first) 
    57                 swap(Ins[vis][i], Ins[vis][i - 1]); 
    58         }
    59         else
    60         {
    61             if (Dell(vis, num)) continue;
    62             Delll(vis);
    63             Del[vis].emplace_back(num); 
    64             for (int len = Del[vis].size(), i = len - 1; i >= 1; --i) if (Del[vis][i] < Del[vis][i - 1])
    65                 swap(Del[vis][i], Del[vis][i - 1]);
    66         }
    67     }
    68 }
    69 
    70 inline bool Com()
    71 {
    72     if (Ins[0].size() != Ins[1].size() || Del[0].size() != Del[1].size()) return false;
    73     for (int i = 0, len = Ins[0].size(); i < len; ++i) if (Ins[0][i].first != Ins[1][i].first || Ins[0][i].second != Ins[1][i].second)
    74         return false;
    75     for (int i = 0, len = Del[0].size(); i < len; ++i) if (Del[0][i] != Del[1][i]) 
    76         return false; 
    77     return true;
    78 }
    79 
    80 inline void Run() 
    81 {
    82     work(0); work(1);
    83     puts(Com() ? "0" : "1");
    84 }
    85 
    86 int main()
    87 {
    88     #ifdef LOCAL
    89         freopen("Test.in", "r", stdin);
    90     #endif
    91 
    92     Run(); 
    93 
    94     return 0; 
    95 }
    View Code

    J - Grid Coloring

    题意:给出一个n * m 的地图,上面有一些点已经涂色,如果已经涂了B 那么从左上角到这个点的矩形都是B 如果是R 那么从右下角的矩形都是R 有一些空点,求有多少种染色方案

    思路:F[i][j][2] 表示 到第i行第j列这个点涂0(‘B’) 或者 涂1('R') 有多少种方案

    如果这个点涂0 那么它左边都是已经确定的 转移的状态就是它下面那个点涂0的方案数+涂1的方案数

    如果这个点涂1,那么它下面都是已经确定了,转移的状态就是它左边那个点涂0的方案数+涂1的方案数

    注意本来就是0和1的情况

     1 #include <bits/stdc++.h> 
     2 using namespace std;
     3 
     4 #define N 50
     5 #define ll long long
     6 
     7 int n, m;
     8 char G[N][N];
     9 ll dp[N][N];
    10 
    11 inline bool Full(int x, int y, int vis)
    12 {
    13     if (!vis)
    14     {
    15         for (int i = 1; i <= x; ++i)
    16             for (int j = 1; j <= y; ++j)
    17             {
    18                 if (G[i][j] == 'R')
    19                     return false;
    20                 G[i][j] = 'B';
    21             }
    22     } 
    23     else
    24     {
    25         for (int i = x; i <= n; ++i)
    26             for (int j = y; j <= m; ++j)
    27             {
    28                 if (G[i][j] == 'B')
    29                     return false;
    30                 G[i][j] = 'R';
    31             }
    32     }
    33     return true;
    34 }
    35 
    36 inline bool work()
    37 {
    38     for (int i = 1; i <= n; ++i)
    39     {
    40         for (int j = 1; j <= m; ++j)
    41         {
    42             if (G[i][j] == 'B')
    43             {
    44                 if (Full(i, j, 0) == false)
    45                     return false;
    46             }
    47             else if (G[i][j] == 'R')
    48             {
    49                 if (Full(i, j, 1) == false)
    50                     return false;
    51             }
    52         }
    53     }
    54     return true;
    55 }
    56 
    57 inline void Run()
    58 {
    59     while (scanf("%d%d", &n, &m) != EOF)
    60     {
    61         for (int i = 1; i <= n; ++i) scanf("%s", G[i] + 1);
    62         if (work() == false) 
    63         {
    64             puts("0");   
    65             continue; 
    66         }
    67         memset(dp, 0, sizeof dp);
    68         for (int i = 1; i <= n; ++i) dp[i][0] = 1;
    69         for (int j = 1; j <= m; ++j) dp[n + 1][j] = 1;
    70         for (int i = n; i >= 1; --i)
    71         {
    72             for (int j = 1; j <= m; ++j)
    73             {
    74                 if (G[i][j] == '.')
    75                 {
    76                     dp[i][j] = dp[i + 1][j] + dp[i][j - 1];
    77                 }
    78                 else if (G[i][j] == 'B')
    79                     dp[i][j] = dp[i + 1][j];
    80                 else
    81                     dp[i][j] = dp[i][j - 1];
    82             }
    83         }
    84         printf("%lld
    ", dp[1][m]);
    85     }
    86 }
    87 
    88 int main()
    89 {
    90     #ifdef LOCAL
    91         freopen("Test.in", "r", stdin);
    92     #endif
    93 
    94     Run(); 
    95 
    96     return 0; 
    97 }
    View Code

    K - Spinning Up Palindromes

    留坑。

    L - Delayed Work

    水(暴力枚举人数)

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 #define INF 0x3f3f3f3f
     6 #define D 1000000
     7 
     8 double k, p, x;
     9 
    10 int main()
    11 {
    12     while (scanf("%lf%lf%lf", &k, &p, &x) != EOF)
    13     {
    14         double ans = INF;
    15         for (int i = 1; i <= D; ++i)
    16         {
    17             double day = (k * 1.0 / i);
    18             ans = min(ans, x * i + p * day);
    19         }
    20         printf("%.3f
    ", ans);
    21     }
    22     return 0;
    23 }
    View Code

    M - Unsatisfying

    留坑。

  • 相关阅读:
    SQL语句大全
    网页常用小技巧
    卡通时钟代码
    舒服的颜色2
    静态代码
    Hibernate工作原理
    SQl多表查询优化 高效率SQL语句
    Hibernate API、对象状态、HQL、Criteria
    MySQL 学习笔记
    intramart知识
  • 原文地址:https://www.cnblogs.com/Dup4/p/9549249.html
Copyright © 2011-2022 走看看