zoukankan      html  css  js  c++  java
  • 2018 Multi-University Training Contest 5 Solution

    A - Always Online

    Unsolved.

    B - Beautiful Now

    Solved.

    题意:

    给出一个n, k  每次可以将n这个数字上的某两位交换,最多交换k次,求交换后的最大和最小值

    思路:

    很明显有一种思路,对于最小值,尽可能把小的放前面, 对于最大值,尽可能把打的放前面。但是如果有多个最小数字或者最大数字会无法得出放哪个好,因此BFS一下即可

      1 #include<bits/stdc++.h>
      2 
      3 using namespace std;
      4 
      5 const int INF = 0x3f3f3f3f;
      6 const int maxn = 1e5 + 10;
      7 
      8 struct node{
      9     int num, idx, step;
     10     node(){}
     11     node(int num, int idx, int step) :num(num), idx(idx), step(step){}
     12 };
     13 
     14 int n, k;
     15 int cnt;
     16 int arr[maxn];
     17 
     18 int BFS1()
     19 {
     20     queue<node>q;
     21     q.push(node(n, cnt, 0));
     22     int ans = INF;
     23     while(!q.empty())
     24     {
     25         node now = q.front();
     26         q.pop();
     27         ans = min(ans, now.num);
     28         if(now.step == k) continue;
     29         if(now.idx == 1) continue;
     30         int tmp = now.num;
     31         cnt = 0;
     32         while(tmp)
     33         {
     34             arr[++cnt] = tmp % 10;
     35             tmp /= 10;
     36         }
     37         int Min = now.idx;
     38         for(int i = now.idx - 1; i >= 1; --i)
     39         {
     40             if(arr[i] == arr[now.idx]) continue;
     41             if(arr[i] == 0 && now.idx == cnt) continue;
     42             if(arr[i] < arr[Min]) Min = i;
     43         }
     44         if(Min == now.idx)
     45         {
     46             q.push(node(now.num, now.idx - 1, now.step));
     47         }
     48         else
     49         {
     50             for(int i = now.idx - 1; i >= 1; --i)
     51             {
     52                 if(arr[i] == arr[Min])
     53                 {
     54                     swap(arr[i], arr[now.idx]);
     55                     tmp = 0;
     56                     for(int j = cnt; j >= 1; --j)
     57                     {
     58                         tmp = tmp * 10 + arr[j];
     59                     }
     60                     q.push(node(tmp, now.idx - 1, now.step + 1));
     61                     swap(arr[i], arr[now.idx]);
     62                 }
     63             }
     64         }
     65     }
     66     return ans;
     67 }
     68 
     69 int BFS2()
     70 {
     71     queue<node>q;
     72     q.push(node(n, cnt, 0));
     73     int ans = -INF;
     74     while(!q.empty())
     75     {
     76         node now = q.front();
     77         q.pop();
     78         ans = max(ans, now.num);
     79         if(now.step == k) continue;
     80         if(now.idx == 1) continue;
     81         int tmp = now.num;
     82         cnt = 0;
     83         while(tmp)
     84         {
     85             arr[++cnt] = tmp % 10;
     86             tmp /= 10;
     87         }
     88         int Max = now.idx;
     89         for(int i = now.idx - 1; i >= 1; --i)
     90         {
     91             if(arr[i] == arr[now.idx]) continue;
     92             if(arr[i] > arr[Max]) Max = i;
     93         }
     94         if(Max == now.idx)
     95         {
     96             q.push(node(now.num, now.idx - 1, now.step));
     97         }
     98         else
     99         {
    100             for(int i = now.idx - 1; i >= 1; --i)
    101             {
    102                 if(arr[i] == arr[Max])
    103                 {
    104                     swap(arr[i], arr[now.idx]);
    105                     tmp = 0;
    106                     for(int j = cnt; j >= 1; --j)
    107                     {
    108                         tmp = tmp * 10 + arr[j];
    109                     }
    110                     q.push(node(tmp, now.idx - 1, now.step + 1));
    111                     swap(arr[i], arr[now.idx]);
    112                 }
    113             }
    114         }
    115     }
    116     return ans;
    117 }
    118 
    119 int main()
    120 {
    121     int t;
    122     scanf("%d", &t);
    123     while(t--)
    124     {
    125         scanf("%d %d", &n ,&k);
    126         int tmp = n;
    127         cnt = 0;
    128         while(tmp)
    129         {
    130             cnt++;
    131             tmp /= 10;
    132         }
    133         k = min(k, cnt - 1);
    134         int ans1 = BFS1();
    135         int ans2 = BFS2();
    136         printf("%d %d
    ", ans1, ans2);
    137     }
    138     return 0;
    139 }
    View Code

    C - Call It What You Want

    Unsolved.

    D - Daylight

    Unsolved.

    E - Everything Has Changed

    Solved.

    题意:

    求多个圆的周长并

    思路:

    对于不想交和内含的直接continue,相切的直接相加。对于相交的可以减去大圆上的弧长,加上小圆的弧长

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 const double PI = acos(-1.0);
     6 const double eps = 1e-8;
     7 
     8 int sgn(double x)
     9 {
    10     if(fabs(x) < eps) return 0;
    11     else return x > 0 ? 1 : -1;
    12 }
    13 
    14 struct Point{
    15     double x, y;
    16     Point(){}
    17     Point(double _x, double _y)
    18     {
    19         x = _x;
    20         y = _y;
    21     }
    22 
    23     double distance(Point p)
    24     {
    25         return hypot(x - p.x, y - p.y);
    26     }
    27 }P;
    28 
    29 int n;
    30 double R, r;
    31 
    32 int main()
    33 {
    34     int t;
    35     scanf("%d", &t);
    36     while(t--)
    37     {
    38         scanf("%d %lf", &n, &R);
    39         double ans = 2 * R * PI;
    40         for(int i = 1; i <= n; ++i)
    41         {
    42             scanf("%lf %lf %lf", &P.x, &P.y, &r);
    43             double dis = P.distance(Point(0.0, 0.0));
    44             if(sgn(dis - (r + R)) >= 0) continue;
    45             else if(sgn(dis - (R - r)) < 0) continue;
    46             else if(sgn(dis - (R - r)) == 0)
    47             {
    48                 ans += 2 * PI * r;
    49                 continue;
    50             }    
    51             double arc1 = (R * R + dis * dis - r * r) / (2.0 * R * dis);
    52             arc1 = 2 * acos(arc1);
    53             double arc2 = (r * r + dis * dis - R * R) / (2.0 * r * dis);
    54             arc2 = 2 * acos(arc2);
    55             ans -= R * arc1;
    56             ans += r * arc2;
    57         }
    58         printf("%.10f
    ", ans);
    59     }    
    60     return 0;
    61 }
    View Code

    F - Fireflies

    Unsolved.

    G - Glad You Came

    Upsolved.

    题意:

    m个区间操作,每次给$[L, R]区间内小于v 的数变为v$

     思路:

    线段树,维护最大最小值+剪枝,因为数据随机才可以这样做。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 5000010
     5 #define M 100010
     6 #define ui unsigned int
     7 #define ll long long
     8 int t, n, m;
     9 ui x, y, z, w;
    10 ui f[N << 2];
    11 ui MOD = (ui)1 << 30;
    12 
    13 ui rng61()
    14 {
    15     x = x ^ (x << 11);
    16     x = x ^ (x >> 4);
    17     x = x ^ (x << 5);
    18     x = x ^ (x >> 14);
    19     w = x ^ y ^ z;
    20     x = y;
    21     y = z;
    22     z = w;
    23     return z;
    24 }
    25 
    26 struct SEG
    27 {
    28     ui lazy[M << 2], Max[M << 2], Min[M << 2];
    29     void Init() 
    30     {
    31         memset(lazy, 0, sizeof lazy);
    32         memset(Max, 0, sizeof Max);
    33         memset(Min, 0, sizeof Min);
    34     }
    35     void pushup(int id) 
    36     { 
    37         Max[id] = max(Max[id << 1], Max[id << 1 | 1]); 
    38         Min[id] = min(Min[id << 1], Min[id << 1 | 1]);
    39     }
    40     void pushdown(int id)
    41     {
    42         if (!lazy[id]) return;
    43         lazy[id << 1] = lazy[id];
    44         Max[id << 1] = lazy[id];
    45         Min[id << 1] = lazy[id];
    46         lazy[id << 1 | 1] = lazy[id];
    47         Max[id << 1 | 1] = lazy[id];
    48         Min[id << 1 | 1] = lazy[id];
    49         lazy[id] = 0;
    50     }
    51     void update(int id, int l, int r, int ql, int qr, ui val)
    52     {
    53         if (Min[id] >= val) return;
    54         if (l >= ql && r <= qr && Max[id] < val)
    55         {
    56             lazy[id] = Max[id] = val;
    57             return;
    58         }
    59         pushdown(id);
    60         int mid = (l + r) >> 1;
    61         if (ql <= mid) update(id << 1, l, mid, ql, qr, val);
    62         if (qr > mid) update(id << 1 | 1, mid + 1, r, ql, qr, val);
    63         pushup(id);
    64     }
    65     int query(int id, int l, int r, int pos)
    66     {
    67         if (l == r) return Max[id];
    68         pushdown(id);
    69         int mid = (l + r) >> 1;
    70         if (pos <= mid) return query(id << 1, l, mid, pos);
    71         else return query(id << 1 | 1, mid + 1, r, pos); 
    72     }
    73 }seg;
    74 
    75 int main()
    76 {
    77     scanf("%d", &t);
    78     while (t--)
    79     {
    80         scanf("%d%d%u%u%u", &n, &m, &x, &y, &z);
    81         for (int i = 1; i <= 3 * m; ++i) f[i] = rng61();
    82         seg.Init();
    83         for (int i = 1, l, r, v; i <= m; ++i)
    84         {
    85             l = f[3 * i - 2] % n + 1;
    86             r = f[3 * i - 1] % n + 1;
    87             v = f[3 * i] % MOD;
    88             if (l > r) swap(l, r);
    89             seg.update(1, 1, n, l, r, v);
    90         }
    91         ll res = 0;
    92         for (int i = 1; i <= n; ++i)
    93             res ^= (ll)seg.query(1, 1, n, i) * (ll)i;
    94         printf("%lld
    ", res);
    95     }
    96     return 0;
    97 }
    View Code

    H - Hills And Valleys

    Upsolved,

    题意:

    给出一个长为n的数字串,每一位范围是$[0, 9]$,可以翻转其中一段,使得最长非下降子序列最长

    思路:

    也就是说 可以存在这样一段

    $0, 1, 2....., x, (x - 1) , y, (y - 1).... x, y + 1, y + 2..$

    我们知道,如果不可以翻转,求最长上升子序列的话,我们可以将原串 和模式串$0123456789$ 求最长公共子序列

    那么翻转的话,我们通过枚举翻转的区间$C(2, 10)$ 构造出上述的模式串,再求最长公共子序列

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 100010
     5 #define INF 0x3f3f3f3f
     6 int t, n, m, a[N], b[20];
     7 int dp[N][20], tl[N][20], tr[N][20], res, l, r, ql, qr;
     8  
     9 void solve()
    10 {
    11     for (int i = 1; i <= m; ++i) dp[0][i] = 0, tl[0][i] = -1, tr[0][i] = -1;
    12     for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j)
    13     {
    14         dp[i][j] = dp[i - 1][j];
    15         tl[i][j] = tl[i - 1][j];
    16         tr[i][j] = tr[i - 1][j]; 
    17         if (a[i] == b[j]) 
    18         {
    19             ++dp[i][j];
    20             if (j == ql && tl[i][j] == -1) tl[i][j] = i;
    21             if (j == qr) tr[i][j] = i;    
    22         }
    23         if (j > 1 && dp[i][j - 1] > dp[i][j])
    24         {
    25             dp[i][j] = dp[i][j - 1];
    26             tl[i][j] = tl[i][j - 1];
    27             tr[i][j] = tr[i][j - 1]; 
    28         }
    29     }
    30     if (ql == 1 && qr == 1) 
    31     {
    32         res = dp[n][m]; 
    33         l = 1;
    34         r = 1;
    35     }
    36     else if (dp[n][m] > res && tl[n][m] != -1 && tr[n][m] != -1)
    37     {
    38         res = dp[n][m];
    39         l = tl[n][m];  
    40         r = tr[n][m];
    41     }
    42 }
    43 
    44 int main()
    45 {
    46     scanf("%d", &t);
    47     while (t--)
    48     {
    49         scanf("%d", &n); 
    50         res = 1, l = 1, r = 1; 
    51         for (int i = 1; i <= n; ++i) scanf("%1d", a + i);
    52         for (int i = 1; i <= 10; ++i) b[i] = i - 1; m = 10;    ql = 1, qr = 1;
    53         solve(); 
    54         for (int i = 1; i < m; ++i) for (int j = i + 1; j <= 10; ++j) 
    55         {
    56             m = 0; 
    57             for (int pos = 1; pos <= i; ++pos) b[++m] = pos - 1;  
    58             ql = m + 1;
    59             for (int pos = j; pos >= i; --pos) b[++m] = pos - 1;
    60             qr = m;
    61             for (int pos = j; pos <= 10; ++pos) b[++m] = pos - 1;
    62             solve();   
    63             //for (int i = 1; i <= m; ++i) printf("%d%c", b[i], " 
    "[i == m]);        
    64         }
    65         printf("%d %d %d
    ", res, l, r);
    66     }
    67     return 0;
    68 }
    View Code

    I - Innocence

    Unsolved.
     

    J - Just So You Know

    Unsolved.

    K - Kaleidoscope

    Unsolved.

    L - Lost In The Echo

    Unsolved.

  • 相关阅读:
    生日蛋糕 (搜索)
    C语言中将二维数组作为函数参数来传递
    HDU 1052 Tian Ji -- The Horse Racing (贪心)(转载有修改)
    HDU 1789 Doing Homework again(排序,DP)
    10.6 ip:网络配置工具
    10.7 netstat:查看网络状态
    10.19 dig:域名查询工具
    10.21 nmap:网络探测工具和安全/端口扫描器
    10.20 host:域名查询工具
    LeetCode Add Two Numbers 两个数相加
  • 原文地址:https://www.cnblogs.com/Dup4/p/9865700.html
Copyright © 2011-2022 走看看