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

    A - Thickest Burger

    水。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 int t;
     5 int a, b;
     6 
     7 int main()
     8 {
     9     scanf("%d" ,&t);
    10     while (t--)
    11     {
    12         scanf("%d%d", &a, &b);
    13         if (a > b) swap(a, b);
    14         printf("%d
    ", a + b * 2);
    15     }
    16     return 0;
    17 }
    View Code

    B - Relative atomic mass

    水。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 int t;
     5 char s[100];
     6 
     7 int main()
     8 {
     9     scanf("%d", &t);
    10     while (t--)
    11     {
    12         scanf("%s", s);
    13         int res = 0;
    14         for (int i = 0, len = strlen(s); i < len; ++i)
    15         {
    16             if (s[i] == 'H') res += 1;
    17             if (s[i] == 'C') res += 12;
    18             if (s[i] == 'O') res += 16;
    19         }
    20         printf("%d
    ", res);
    21     }
    22     return 0;
    23 }
    View Code

    C - Recursive sequence

    题意:求$F[n] = F[n - 1] + 2 cdot F[n - 2] + n^4$

    思路:考虑

    $n^4 = (n - 1)^4 + 4 cdot (n - 1) ^ 3 + 6 cdot (n - 1) ^2 + 4 cdot (n - 1) ^ 2 + (n - 1) + 1$

    然后进行递推即可

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define ll long long
     5 
     6 const ll MOD = 2147493647;
     7 
     8 int t;
     9 ll n, a, b;
    10 
    11 struct node
    12 {
    13     ll a[7][7];
    14     node () { memset(a, 0, sizeof a); }
    15     node operator * (const node &r) const
    16     {
    17         node ans = node();
    18         for (int i = 0; i < 7; ++i) for (int j = 0; j < 7; ++j) for (int k = 0; k < 7; ++k)
    19             ans.a[i][j] = (ans.a[i][j] + a[i][k] * r.a[k][j] % MOD) % MOD;
    20         return ans;
    21     }
    22 };
    23 
    24 ll tmp[7][7] = 
    25 {
    26     1, 1, 0, 0, 0, 0, 0,
    27     2, 0, 0, 0, 0, 0, 0,
    28     1, 0, 1, 0, 0, 0, 0,
    29     4, 0, 4, 1, 0, 0, 0,
    30     6, 0, 6, 3, 1, 0, 0,
    31     4, 0, 4, 3, 2, 1, 0,
    32     1, 0, 1, 1, 1, 1, 1,
    33 };
    34 
    35 ll tmp2[7] = 
    36 {
    37     0, 0, 16, 8, 4, 2, 1,
    38 };
    39 
    40 node qmod(ll n)
    41 {
    42     node base = node();
    43     for (int i = 0; i < 7; ++i) for (int j = 0; j < 7; ++j)
    44         base.a[i][j] = tmp[i][j];
    45     node res = node();
    46     for (int i = 0; i < 7; ++i) res.a[0][i] = tmp2[i];
    47     while (n)
    48     {
    49         if (n & 1) res = res * base;
    50         base = base * base;
    51         n >>= 1;
    52     }
    53     return res;
    54 }
    55 
    56 int main()
    57 {
    58     scanf("%d", &t);
    59     while (t--)
    60     {
    61         scanf("%lld%lld%lld", &n, &a, &b);
    62         if (n == 1) printf("%lld
    ", a);
    63         else if (n == 2) printf("%lld
    ", b);
    64         else
    65         {
    66             tmp2[0] = b; tmp2[1] = a;
    67             printf("%lld
    ", qmod(n - 2).a[0][0]);
    68         }
    69     }
    70     return 0;
    71 }
    View Code

    D - Winning an Auction

    留坑。

    E - Counting Cliques

    题意:给出n个点,m条边,求点集大小为S的完全图个数

    思路:以每个点为起点搜有多少完全图

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 const int maxn = 1e2 + 10;
     6 
     7 int n, m, s;
     8 int ans;
     9 int arr[maxn], tot;
    10 int mp[maxn][maxn];
    11 vector<int>G[maxn];
    12 
    13 void Init(int N)
    14 {
    15     ans = 0;
    16     for(int i = 1; i <= N; ++i)
    17     {
    18         G[i].clear();
    19         mp[i][i] = 1;
    20         for(int j = i + 1; j <= N; ++j)
    21         {
    22             mp[i][j] = mp[j][i] = 0;
    23         }
    24     }
    25 }
    26 
    27 void DFS(int u, int cnt)
    28 {
    29     if(cnt == s)
    30     {
    31         ++ans;
    32         return ;
    33     }
    34     for(auto it: G[u])
    35     {
    36         bool flag = true;
    37         for(int i = 0; i < tot; ++i)
    38         {
    39             if(!mp[arr[i]][it]) 
    40             {
    41                 flag = false;
    42                 break;
    43             }
    44         }
    45         if(flag)
    46         {
    47             arr[tot++] = it;
    48             DFS(it, cnt + 1);
    49             tot--;
    50         }
    51     }
    52 }
    53 
    54 int main()
    55 {
    56     int t;
    57     scanf("%d", &t);
    58     while(t--)
    59     {
    60         scanf("%d %d %d", &n, &m, &s);
    61         Init(n);
    62         for(int i = 1; i <= m; ++i)
    63         {
    64             int u, v;
    65             scanf("%d %d", &u, &v);
    66             G[u].push_back(v);
    67             mp[u][v] = mp[v][u] = 1;
    68         }
    69         for(int i = 1; i <= n; ++i)
    70         {
    71             tot = 0;
    72             arr[tot++] = i;
    73             DFS(i, 1);
    74         }
    75         printf("%d
    ", ans);
    76     }
    77     return 0;
    78 }
    View Code

    G - Do not pour out

    题意:有一个底部为直径为2的圆,高度为2的桶,现在里面有高度为h的液体,将桶倾斜至最大,求上表面面积

    思路:分类,若经过没经过底部则为PI / cos(2.0-d)

    否则二分+积分求面积

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 const double eps = 1e-20;
     6 const double PI = acos(-1.0);
     7 
     8 int sgn(double x)
     9 {
    10     if(fabs(x) < eps) return 0;
    11     else return x > 0 ? 1 : -1;
    12 }
    13 
    14 double d;
    15 
    16 double calc(double arc)
    17 {
    18     return PI * cos(arc) - arc * cos(arc) + sin(arc) - sin(arc) * sin(arc) * sin(arc) / 3.0;
    19 }
    20 
    21 int check(double mid)
    22 {
    23     double tmp = (calc(acos(2.0 * tan(mid) - 1.0)) - calc(PI)) / tan(mid);
    24     return sgn(tmp - d * PI);
    25 }
    26 
    27 double get(double l, double r)
    28 {
    29     if(check(l) == 0) return l;
    30     int cnt = 256;
    31     while(cnt--)
    32     {
    33         double mid = (l + r) / 2.0;
    34         int tmp = check(mid);
    35         if(tmp == 0) return mid;
    36         if(tmp == 1) r = mid;
    37         if(tmp == -1) l = mid;
    38     }
    39     return l;
    40 }
    41 
    42 int main()
    43 {
    44     int t;
    45     scanf("%d", &t);
    46     while(t--)
    47     {
    48         scanf("%lf", &d);
    49         if(sgn(d) == 0)
    50         {
    51             printf("0.00000
    ");
    52         }
    53         else if(sgn(d - 1) > 0)
    54         {
    55             double arc = atan(2.0 - d);
    56             double ans = PI / cos(arc);
    57             printf("%.5f
    ", ans);
    58         }
    59         else
    60         {
    61             double tmp = get(eps, PI / 4.0);
    62             double t1 = 2.0 * tan(tmp) - 1.0;
    63             double arc = acos(t1);
    64             double ans = PI - arc + cos(arc) * sin(arc);
    65             ans = ans / sin(tmp);
    66             printf("%.5f
    ", ans);
    67         }
    68     }
    69     return 0;
    70 }
    View Code

    H - Guessing the Dice Roll

    留坑。

    I - The Elder

    题意:给出一棵树,每个点到根节点1的方式可以是连续走,也可以经过一个点消耗时间p,使得重新计算所经过路径,求每个点到根节点最小的最大时间   时间为$L^2$

    思路:考虑朴素的转移 $F[i] = min(F[j] + p + (sum[i] - sum[j]) ^ 2) (j 为 i 的祖先们)$

    拆分式子

    $F[i] = F[j] + p + {sum[i]} ^ 2 - 2 cdot sum[i] cdot sum[j] + {sum[j]} ^ 2$

    $F[j] = F[i] + 2 cdot sum[i] cdot sum[j] - p - {sum[i]} ^ 2 - {sum[j]} ^ 2$

    考虑斜率优化

    树上的单调队列优化可以通过标记最后一个更改的值,然后还原(XHT)

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 typedef long long ll;
     6 
     7 const int maxn = 1e5 + 10;
     8 
     9 struct Edge{
    10     int to, nxt;
    11     ll w;
    12     Edge(){}
    13     Edge(int to, int nxt, ll w): to(to), nxt(nxt), w(w){}
    14 }edge[maxn << 1];
    15 
    16 ll ans;
    17 ll dis[maxn];
    18 ll dp[maxn];
    19 int n, p;
    20 int que[maxn];
    21 int head[maxn], tot;
    22 
    23 void Init(int N)
    24 {
    25     for(int i = 1; i <= N; ++i) head[i] = -1;
    26     tot = ans = 0;
    27 }
    28 
    29 void addedge(int u, int v, ll w)
    30 {
    31     edge[tot] = Edge(v, head[u], w);
    32     head[u] = tot++;
    33 }
    34 
    35 ll dy(int j, int k)
    36 {
    37     return dp[j] - dp[k] + dis[j] * dis[j] - dis[k] * dis[k];
    38 }
    39 
    40 ll dx(int j, int k)
    41 {
    42     return 2 * (dis[j] - dis[k]);
    43 }
    44 
    45 void DFS(int u, int fa, int l, int r)
    46 {
    47     int remind = -1;
    48     
    49     if(u != 1)
    50     {
    51         while(l < r && dy(que[l + 1], que[l]) <= dis[u] * dx(que[l + 1], que[l])) l++;
    52 //        cout << u << " " << que[l] << " " << dp[que[l]] + p + (dis[u] - dis[que[l]]) * (dis[u] - dis[que[l]]) << endl;
    53         dp[u] = min(dis[u] * dis[u], dp[que[l]] + p + (dis[u] - dis[que[l]]) * (dis[u] - dis[que[l]]));
    54         while(l < r && dy(que[r], que[r - 1]) * dx(u, que[r]) >= dy(u, que[r]) * dx(que[r], que[r - 1])) r--;
    55         remind = que[++r];
    56         que[r] = u;
    57     }
    58 
    59     ans = max(ans, dp[u]);
    60 
    61     for(int i = head[u]; ~i; i = edge[i].nxt)
    62     {
    63         int v = edge[i].to;
    64         if(v == fa) continue;
    65         dis[v] = dis[u] + edge[i].w;
    66         DFS(v, u, l, r);
    67     }
    68 
    69     if(remind != -1) que[r] = remind;
    70 }
    71 
    72 
    73 int main()
    74 {
    75     int t;
    76     scanf("%d", &t);
    77     while(t--)
    78     {
    79         scanf("%d %d", &n, &p);
    80         Init(n);
    81         for(int i = 1; i < n; ++i)
    82         {
    83             int u, v, w;
    84             scanf("%d %d %d", &u, &v ,&w);
    85             addedge(u, v, w);
    86             addedge(v, u, w);
    87         }
    88         DFS(1, -1, 1, 0);
    89 //        for(int i = 1; i <= n; ++i) cout << i << " " << dp[i] << endl;
    90         printf("%lld
    ", ans);
    91     }
    92     return 0;
    93 }
    View Code

    J - Query on a graph

    留坑。

    K - New Signal Decomposition

    留坑。

    L - A Random Turn Connection Game

    留坑。

    M - Subsequence

    留坑。

  • 相关阅读:
    MSSQL经典语句
    注销时关闭当前窗体,返回登入界面
    自定义控件小结进阶篇
    精妙SQL语句大全
    触发器MSSQL常用操作
    经典SQL语句大全
    文件下载
    android Notification 的使用
    startActivityForResult()的用法
    Android手机中获取手机号码和运营商信息
  • 原文地址:https://www.cnblogs.com/Dup4/p/9786924.html
Copyright © 2011-2022 走看看