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

    A:Exam

    Solved.

    温暖的签。

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 const int maxn = 1e3 + 10;
     6 
     7 int k;
     8 char str1[maxn], str2[maxn];
     9 
    10 int main()
    11 {
    12     while(~scanf("%d",&k))
    13     {
    14         scanf("%s", str1 + 1);
    15         scanf("%s", str2 + 1);
    16         int cnt1 = 0, cnt2 = 0;
    17         int len = strlen(str1 + 1);
    18         for(int i = 1; i <= len; ++i)
    19         {
    20             if(str1[i] == str2[i]) cnt1++;
    21             else cnt2++;
    22         }
    23         int ans = 0;
    24         if(cnt1 >= k)
    25         {
    26             ans = k + cnt2;
    27         }
    28         else 
    29         {
    30             ans = len - (k - cnt1);
    31         }
    32         printf("%d
    ", ans);
    33     }
    34     return 0;
    35 }
    View Code

    B:Coprime Integers

    Solved.

    枚举gcd反演

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 typedef long long ll;
     6 
     7 const int maxn = 1e7 + 10;
     8 
     9 bool check[maxn];
    10 int prime[maxn];
    11 ll mu[maxn];
    12 
    13 void Moblus()
    14 {
    15     memset(check, false, sizeof check);
    16     mu[1] = 1;
    17     int tot = 0;
    18     for(int i = 2; i < maxn; ++i)
    19     {
    20         if(!check[i])
    21         {
    22             prime[tot++] = i;
    23             mu[i] = -1;
    24         }
    25         for(int j = 0; j < tot; ++j)
    26         {
    27             if(i * prime[j] > maxn) break;
    28             check[i * prime[j]] = true;
    29             if(i % prime[j] == 0)
    30             {
    31                 mu[i * prime[j]] = 0;
    32                 break;
    33             }
    34             else 
    35             {
    36                 mu[i * prime[j]] = -mu[i];
    37             }
    38         }
    39     }
    40 }
    41 
    42 ll sum[maxn];
    43 
    44 ll calc(int n, int m)
    45 {
    46     ll ans = 0;
    47     if(n > m) swap(n, m);
    48     for(int i = 1, la = 0; i <= n; i = la + 1)
    49     {
    50         la = min(n / (n / i), m / (m / i));
    51         ans += (ll)(sum[la] - sum[i - 1]) * (n / i) * (m / i);
    52     }
    53     return ans;
    54 }    
    55 
    56 ll a, b, c, d;
    57 
    58 int main()
    59 {
    60     Moblus();
    61     for(int i = 1; i < maxn; ++i) sum[i] = sum[i - 1] + mu[i];
    62     while(~scanf("%lld %lld %lld %lld", &a, &b, &c, &d))
    63     {
    64         ll ans = calc(b, d) - calc(a - 1, d) - calc(b, c - 1) + calc(a - 1, c - 1);
    65         printf("%lld
    ", ans);
    66     }
    67     return 0;
    68 }
    View Code

    C:Contest Setting

    Solved.

    题意:

    有n个题目,每个题目的难度值不同,要选出k个组成一套$Contest$

    要求每个题目难度不同,求方案数

    思路:

    $把难度值相同的题目放在一起作为一种 dp[i][j] 表示选到第i种题目,已经选了k种的方案数$

    $然后做01背包即可,注意加上的值为cnt[i] 表示该种题目有多少个$

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 typedef long long ll;
     6 
     7 const ll MOD = 998244353;
     8 const int maxn = 1e3 + 10;
     9 
    10 int n, k, pos;
    11 ll cnt[maxn];
    12 ll dp[maxn];
    13 map<int, int>mp;
    14 
    15 int main()
    16 {
    17     while(~scanf("%d %d", &n, &k))
    18     {
    19         mp.clear();
    20         pos = 0;
    21         memset(cnt, 0, sizeof cnt);
    22         for(int i = 1; i <= n; ++i)
    23         {
    24             int num;
    25             scanf("%d", &num);
    26             if(mp[num] == 0) mp[num] = ++pos;
    27             int id = mp[num];
    28             cnt[id]++;
    29         }
    30         memset(dp, 0, sizeof dp);
    31         dp[0] = 1;
    32         for(int i = 1; i <= pos; ++i)
    33         {
    34             for(int j = k; j >= 1; --j)
    35             {
    36                 dp[j] = (dp[j] + dp[j - 1] * cnt[i] % MOD) % MOD;
    37             }
    38         }
    39         printf("%lld
    ", dp[k]);
    40     }
    41     return 0;
    42 }
    View Code

    D:Count The Bits

    Solved.

    题意:

    在$[0, 2^b - 1] 中所有k的倍数以二进制形式表示有多少个1$

    思路:

    $dp[i][j] 表示枚举二进制位数,j 模k的余数, 表示的是前i位中模k的余数为j的数中1的个数$

    $cnt[i][j] 表示当前二进制位为第i位, 模k的余数为j的数的个数$

    直接转移即可。

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 typedef long long ll;
     6 
     7 const ll MOD = (ll)1e9 + 9;
     8 const int maxn = 1e3 + 10;
     9 
    10 int k, b;
    11 ll cnt[maxn][maxn];
    12 ll dp[maxn][maxn];
    13 
    14 int main()
    15 {
    16     while(~scanf("%d %d", &k, &b))
    17     {
    18         memset(cnt, 0, sizeof cnt);
    19         memset(dp, 0, sizeof dp);
    20         cnt[1][0]++;
    21            cnt[1][1 % k]++;
    22         dp[1][1 % k]++;
    23         ll tmp = 1;
    24         for(int i = 1; i <= b; ++i)
    25         {
    26             tmp = (tmp << 1) % k;
    27             for(int j = 0; j < k; ++j)
    28             {
    29                 //0
    30                 cnt[i + 1][j] = (cnt[i + 1][j] + cnt[i][j]) % MOD;
    31                 dp[i + 1][j] = (dp[i + 1][j] + dp[i][j]) % MOD;
    32                 //1
    33                 ll tmp2 = (tmp + j) % k;
    34                 cnt[i + 1][tmp2] = (cnt[i + 1][tmp2] + cnt[i][j]) % MOD;
    35                 dp[i + 1][tmp2] = ((dp[i + 1][tmp2] + cnt[i][j]) % MOD + dp[i][j]) % MOD;
    36             }
    37         }
    38         printf("%lld
    ", dp[b][0]);
    39     }
    40     return 0;
    41 }
    View Code
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 1010
     5 #define ll long long
     6 const ll MOD = (ll)1e9 + 9;
     7 ll dp[N][N], cnt[N][N];
     8 int n, k;
     9 
    10 int main()
    11 {
    12     while (scanf("%d%d", &k, &n) != EOF)
    13     {
    14         memset(dp, 0, sizeof dp);
    15         memset(cnt, 0, sizeof cnt);
    16         ++dp[1][1 % k];
    17         ++cnt[1][1 % k];
    18         ++cnt[1][0];     
    19         ll tmp = 1 % k;  
    20         for (int i = 2; i <= n; ++i)
    21         {
    22             tmp = tmp * 2 % k; 
    23             for (int j = 0; j < k; ++j) 
    24             {
    25                 dp[i][j] = dp[i - 1][j];   
    26                 cnt[i][j] = cnt[i - 1][j]; 
    27                 if (j - tmp >= 0) 
    28                 {
    29                     dp[i][j] = (dp[i][j] + dp[i - 1][j - tmp] + cnt[i - 1][j - tmp]) % MOD;
    30                     cnt[i][j] = (cnt[i][j] + cnt[i - 1][j - tmp]) % MOD; 
    31                 }
    32                 else 
    33                 {
    34                     dp[i][j] = (dp[i][j] + dp[i - 1][k + j - tmp] + cnt[i - 1][k + j - tmp]) % MOD;
    35                     cnt[i][j] = (cnt[i][j] + cnt[i - 1][k + j - tmp]) % MOD; 
    36                 }
    37             }    
    38         }
    39         printf("%lld
    ", dp[n][0]);
    40     }
    41     return 0;
    42 }
    View Code

    E:Cops And Robbers

    Solved.

    题意:

    在一个$n * m 的矩阵中,有些地方可以建墙,但是不同的墙开销不同,求最小开销把劫匪围住$

    思路:

    拆点最小割,但是是点权,拆点即可。

      1 #include<bits/stdc++.h>
      2 
      3 using namespace std; 
      4 
      5 const int maxn = 4e3 + 10;
      6 const int INF = 0x3f3f3f3f;
      7 
      8 struct Edge{
      9     int to, flow, nxt;
     10     Edge(){}
     11     Edge(int to, int nxt, int flow):to(to), nxt(nxt), flow(flow){}
     12 }edge[maxn << 2];
     13 
     14 int head[maxn], dep[maxn];
     15 int S,T;
     16 int N, n, m, tot;
     17 
     18 void Init(int n)
     19 {
     20     N = n;
     21     //memset(head, -1, sizeof head);
     22     for(int i = 0; i < N; ++i) head[i] = -1;
     23     tot = 0;
     24 }
     25 
     26 void addedge(int u, int v, int w, int rw = 0)
     27 {
     28     edge[tot] = Edge(v, head[u], w); head[u] = tot++;
     29     edge[tot] = Edge(u, head[v], rw); head[v] = tot++;
     30 }
     31 
     32 bool BFS()
     33 {
     34     //memset(dep, -1, sizeof dep);
     35     for(int i = 0; i < N; ++i) dep[i] = -1;
     36     queue<int>q;
     37     q.push(S);
     38     dep[S] = 1;
     39     while(!q.empty())
     40     {
     41         int u = q.front();
     42         q.pop();
     43         for(int i = head[u]; ~i; i = edge[i].nxt)
     44         {
     45             if(edge[i].flow && dep[edge[i].to] == -1)
     46             {
     47                 dep[edge[i].to] = dep[u] + 1;
     48                 q.push(edge[i].to);
     49             }
     50         }
     51     }
     52     return dep[T] < 0 ? 0 : 1;
     53 }
     54 
     55 int DFS(int u, int f)
     56 {
     57     if(u == T || f == 0) return f;
     58     int w, used = 0;
     59     for(int i = head[u]; ~i; i = edge[i].nxt)
     60     {
     61         if(edge[i].flow && dep[edge[i].to] == dep[u] + 1)
     62         {
     63             w = DFS(edge[i].to, min(f - used, edge[i].flow));
     64             edge[i].flow -= w;
     65             edge[i ^ 1].flow += w;
     66             used += w;
     67             if(used == f) return f;
     68         }
     69     }
     70     if(!used) dep[u] = -1;
     71     return used;
     72 }
     73 
     74 int Dicnic()
     75 {
     76     int ans = 0;
     77     while(BFS())
     78     {
     79         int tmp = DFS(S, INF); 
     80         if(tmp == INF) return -1;
     81         ans += tmp;
     82     }
     83     return ans;
     84 }
     85 
     86 int c;
     87 int C[maxn];
     88 char mp[100][100];
     89 
     90 int calc(int i, int j)
     91 {
     92     return i * 31 + j;
     93 }
     94 
     95 int main()
     96 {
     97     while(~scanf("%d %d %d", &m, &n, &c))
     98     {
     99         int base = n * 31 + m + 31;
    100         int x, y;
    101         Init(4000);
    102         for(int i = 1; i <= n; ++i)
    103         {
    104             for(int j = 1; j <= m; ++j)
    105             {
    106                 scanf(" %c", &mp[i][j]);
    107                 if(mp[i][j] == 'B') { x = i, y = j; }
    108             }
    109         }
    110         for(int i = 1; i <= c; ++i) scanf("%d", C + i);
    111         S = 0, T = calc(x, y);
    112         for(int i = 1; i <= n; ++i)
    113         {
    114             addedge(S, calc(i, 1), INF);
    115             addedge(S, calc(i, m), INF);    
    116         }
    117         for(int i = 1; i <= m; ++i)
    118         {
    119             addedge(S, calc(1, i), INF);
    120             addedge(S, calc(n, i), INF);
    121         }
    122         for(int i = 1; i <= n; ++i)
    123         {
    124             for(int j = 1; j <= m; ++j)
    125             {
    126                 if(i != n)
    127                 {
    128                     addedge(calc(i, j) + base, calc(i + 1, j), INF);
    129                     addedge(calc(i + 1, j) + base, calc(i, j), INF);
    130                 }
    131                 if(j != m)
    132                 {
    133                     addedge(calc(i, j)+ base, calc(i, j + 1), INF);
    134                     addedge(calc(i, j + 1) + base, calc(i, j), INF);
    135                 }
    136             }
    137         }
    138         for(int i = 1; i <= n; ++i)
    139         {
    140             for(int j = 1; j <= m; ++j)
    141             {
    142                 if(mp[i][j] >= 'a' && mp[i][j] <= 'z')
    143                 {
    144                     addedge(calc(i, j), calc(i, j) + base, C[mp[i][j] - 'a' + 1]);
    145                 }
    146                 else 
    147                 {
    148                     addedge(calc(i, j), calc(i, j) + base, INF);
    149                 }
    150             }
    151         }
    152         int ans = Dicnic();
    153         printf("%d
    ", ans);
    154     }
    155     return 0;
    156 }
    View Code

    F:Rectangles

    Solved.

    题意:

    二维平面上有一些平行坐标轴的矩形,求有多少区间是被奇数个矩形覆盖。

    思路:

    扫描线,只是把区间加减换成区间01状态翻转,现场学扫描线可还行..

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 #define ll long long
      5 #define N 200010
      6 #define pii pair <int, int>
      7 int n, mx, my, bx[N], by[N];
      8 ll res;
      9 struct Rec
     10 {
     11     int x[2], y[2]; 
     12     void scan()
     13     {
     14         for (int i = 0; i < 2; ++i) scanf("%d%d", x + i, y + i);
     15         if (x[0] > x[1]) swap(x[0], x[1]);
     16         if (y[0] > y[1]) swap(y[0], y[1]);
     17         bx[++mx] = x[0];
     18         bx[++mx] = x[1];
     19         by[++my] = y[0];
     20         by[++my] = y[1]; 
     21     }
     22 }rec[N];
     23 vector <pii> v[N];  
     24 
     25 void Hash()
     26 {
     27     sort(bx + 1, bx + 1 + mx);
     28     sort(by + 1, by + 1 + my);
     29     mx = unique(bx + 1, bx + 1 + mx) - bx - 1;
     30     my = unique(by + 1, by + 1 + my) - by - 1;
     31     for (int i = 1; i <= n; ++i) 
     32     {
     33         for (int j = 0; j < 2; ++j)
     34         {
     35             rec[i].x[j] = lower_bound(bx + 1, bx + 1 + mx, rec[i].x[j]) - bx;
     36             rec[i].y[j] = lower_bound(by + 1, by + 1 + my, rec[i].y[j]) - by; 
     37         }
     38     }
     39 }
     40 
     41 namespace SEG
     42 {
     43     struct node
     44     {
     45         ll sum, val;
     46         int lazy; 
     47         node () {}
     48         node (ll sum, ll val, int lazy) : sum(sum), val(val), lazy(lazy) {}
     49         void init() { sum = val = lazy = 0; }
     50         node operator + (const node &other) const { return node(sum + other.sum, val + other.val, 0); }
     51         void Xor() { val = sum - val; lazy ^= 1; }   
     52     }a[N << 2];
     53     void build(int id, int l, int r)
     54     {
     55         a[id] = node(0, 0, 0);
     56         if (l == r) 
     57         {
     58             a[id].sum = by[l + 1] - by[l];
     59             return;
     60         }
     61         int mid = (l + r) >> 1;
     62         build(id << 1, l, mid);
     63         build(id << 1 | 1, mid + 1, r);
     64         a[id] = a[id << 1] + a[id << 1 | 1];
     65     }
     66     void pushdown(int id)
     67     {
     68         if (!a[id].lazy) return;
     69         a[id << 1].Xor();
     70         a[id << 1 | 1].Xor();
     71         a[id].lazy = 0;
     72     }
     73     void update(int id, int l, int r, int ql, int qr)
     74     {
     75         if (l >= ql && r <= qr) 
     76         {
     77             a[id].Xor();
     78             return;
     79         }
     80         int mid = (l + r) >> 1;
     81         pushdown(id);
     82         if (ql <= mid) update(id << 1, l, mid, ql, qr);
     83         if (qr > mid) update(id << 1 | 1, mid + 1, r, ql, qr);
     84         a[id] = a[id << 1] + a[id << 1 | 1];
     85     }
     86 }
     87 
     88 int main()
     89 {
     90     while (scanf("%d", &n) != EOF)
     91     {
     92         mx = my = 0; res = 0; 
     93         for (int i = 1; i <= 2 * n; ++i) v[i].clear();
     94         for (int i = 1; i <= n; ++i) rec[i].scan(); Hash();    
     95         for (int i = 1; i <= n; ++i) 
     96         {
     97             v[rec[i].x[0]].emplace_back(rec[i].y[0], rec[i].y[1] - 1);
     98             v[rec[i].x[1]].emplace_back(rec[i].y[0], rec[i].y[1] - 1); 
     99         }
    100         n <<= 1;    
    101         SEG::build(1, 1, n);  
    102         for (int i = 1; i < mx; ++i)
    103         {
    104             for (auto it : v[i]) SEG::update(1, 1, n, it.first, it.second);
    105             res += (bx[i + 1] - bx[i]) * SEG::a[1].val;    
    106         }
    107         printf("%lld
    ", res); 
    108     }
    109     return 0;
    110 }
    View Code

    G:Goat on a Rope

    Solved.

    签到。

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 double x, y;
     6 double xa, xb, ya, yb;
     7 
     8 double calc(double xa, double ya, double xb, double yb)
     9 {
    10     return sqrt((xa - xb) * (xa - xb) + (ya - yb) * (ya - yb));
    11 }
    12 
    13 int main()
    14 {
    15     while(~scanf("%lf %lf %lf %lf %lf %lf", &x, &y, &xa, &ya, &xb, &yb))
    16     {
    17         double ans = 1e9;
    18         if(x >= min(xa, xb) && x <= max(xa, xb)) ans = min(ans, min(fabs(y - ya), fabs(y - yb)));
    19         if(y >= min(ya, yb) && y <= max(ya, yb)) ans = min(ans, min(fabs(x - xa), fabs(x - xb)));
    20         ans = min(ans, calc(x, y, xa, ya));
    21         ans = min(ans, calc(x, y, xa, yb));
    22         ans = min(ans, calc(x, y, xb, ya));
    23         ans = min(ans, calc(x, y, xb, yb));
    24         printf("%.3f
    ", ans);
    25     }
    26     return 0;
    27 }
    View Code

    H:Repeating Goldbachs

    Solved.

    签到。

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 const int maxn = 1e6 + 10;
     6 
     7 bool isprime[maxn];
     8 int prime[maxn];
     9 
    10 void Init()
    11 {
    12     memset(isprime, true, sizeof isprime);
    13     isprime[0] = isprime[1] = false;
    14     for(int i = 2; i < maxn; ++i)
    15     {
    16         if(isprime[i])
    17         {
    18             prime[++prime[0]] = i;
    19             for(int j = i * 2; j < maxn; j += i)
    20             {
    21                 isprime[j] = false;
    22             }
    23         }
    24     }
    25 }
    26 
    27 int x;
    28 
    29 int main()
    30 {
    31     Init();
    32     while(~scanf("%d", &x))
    33     {
    34         int ans = 0;
    35         while(x >= 4)
    36         {
    37             for(int i = 1; i <= prime[0]; ++i)
    38             {
    39                 int tmp = prime[i];
    40                 if(isprime[x - tmp])
    41                 {
    42                     ++ans;
    43                     x = x - tmp - tmp;
    44                     break;
    45                 }
    46             }
    47         }
    48         printf("%d
    ", ans);
    49     }
    50     return 0;
    51 }
    View Code

    I:Inversions

    Unsolved.

    题意:

    给出一些序列,一些位置上的数字可以在$[1, k]的范围内随便填,求如果填使得整个序列的逆序对个数最多$

    J:Time Limits

    Solved.

    签到。

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 int n, s;
     6 
     7 int main()
     8 {
     9     while(~scanf("%d %d", &n, &s))
    10     {
    11         int Max = -1;
    12         for(int i = 1; i <= n; ++i)
    13         {
    14             int num;
    15             scanf("%d", &num);
    16             Max = max(Max, num);
    17         }
    18         Max *= s;
    19         int ans = Max / 1000;
    20         if(Max % 1000) ans++;
    21         printf("%d
    ", ans);
    22     }
    23     return 0;
    24 }
    View Code

    K:Knockout

    Unsolved.

    题意:

    给出一个数字,然后两个骰子的点数,每次可以移掉数字当中某几位加起来的和等于两骰子点数之和

    那么就可以移掉这几位,知道最后不能移位置,最后剩下的数就是分数

    现在给出一中间局面,求移掉哪些,使得最后的分数期望最大以及最小

    L:Liars

    Solved.

    签到。

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 const int maxn = 1e3 + 10;
     6 
     7 int n;
     8 int cnt[maxn];
     9 
    10 int main()
    11 {
    12     while(~scanf("%d", &n))
    13     {
    14         memset(cnt, 0, sizeof cnt);
    15         for(int i = 1; i <= n; ++i)
    16         {
    17             int ai, bi;
    18             scanf("%d %d", &ai, &bi);
    19             for(int j = ai; j <= bi; ++j)
    20             {
    21                 cnt[j]++;
    22             }
    23         }
    24         int ans = -1;
    25         for(int i = 1; i <= n; ++i)
    26         {
    27             if(cnt[i] == i) ans = i;
    28         }
    29         printf("%d
    ", ans);
    30     }
    31     return 0;
    32 }
    View Code

    M:Mobilization

    Unsolved.

    题意:

    $有m种军队,每种军队有h_i 属性 和 p_i属性,以及购买一支军队需要c_i的钱,每种军队可以购买无限支$

    $现在你有C个单位的钱,求如何购买军队,使得sum h_i cdot sum p_i 最大$

  • 相关阅读:
    三、FileStream 文件流基本操作
    NetCore3.1+Flurl..Http_FluentHttp 增删改查
    CryptoJS与C#AES加解密互转
    C#生成随机字符串
    IIS发布网站之后,页面图片和js未加载出错
    web中浏览PDF文件
    ASP.NET下使用Combres对JS、CSS合并和压缩
    jQuery截取字符串、日期字符串转Date、获取html中的纯文本
    jquery格式化时间
    jQuery限制文本框的输入长度
  • 原文地址:https://www.cnblogs.com/Dup4/p/10086500.html
Copyright © 2011-2022 走看看