zoukankan      html  css  js  c++  java
  • 2020大一个人赛(10)题解 2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1)

    2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1)部分题

    A - Exam

    题意:给你k(朋友正确个数)和两个字符串(你和你朋友的答案),问你能答对的最大个数

    思路:找你和朋友相同的个数,然后进行判断就行。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<vector>
     4 #include<map>
     5 #include<cstring>
     6 using namespace std;
     7 #define ll long long
     8 const int N = 2e6+25;
     9 const int mod = 1e9 + 7;
    10 ll a[N];
    11 int main()
    12 {
    13     ll n, ans = 0, sum = 0;
    14     cin >> n;
    15     string s1, s2;
    16     cin >> s1 >> s2;
    17     for (int i = 0; i < s1.size(); i++)
    18     {
    19         if (s1[i] == s2[i])
    20             ans++;
    21         else
    22             sum++;
    23     }
    24     if (ans == n)
    25         cout << s1.size() << endl;
    26     else if (ans > n)
    27         cout << n + sum << endl;
    28     else cout << s1.size() - (n - ans) << endl;
    29     
    30    
    31 
    32 }

    B - Coprime Integers

     题意:给你区间【a,b】【c,d】,问你互质整数对的数量。

    思路:莫比乌斯反演算法,反演公式如下:(群里有模板OvO)

    献上代码

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<vector>
     4 #include<map>
     5 #include<cstring>
     6 using namespace std;
     7 #define ll long long
     8 const int N = 1e7+2;
     9 const int mod = 1e9 + 7;
    10 const int MAXN = 1e7+2;
    11 bool check[MAXN + 10];
    12 int prime[MAXN + 10];
    13 int mu[MAXN + 10];
    14 void Moblus()
    15 {
    16     memset(check, false, sizeof(check));
    17     mu[1] = 1;
    18     int tot = 0;
    19     for (int i = 2; i <= MAXN; i++)
    20     {
    21         if (!check[i])
    22         {
    23             prime[tot++] = i;
    24             mu[i] = -1;
    25         }
    26         for (int j = 0; j < tot; j++)
    27         {
    28             if (i * prime[j] > MAXN) break;
    29             check[i * prime[j]] = true;
    30             if (i % prime[j] == 0)
    31             {
    32                 mu[i * prime[j]] = 0;
    33                 break;
    34             }
    35             else
    36             {
    37                 mu[i * prime[j]] = -mu[i];
    38             }
    39         }
    40     }
    41 }
    42 int sum[MAXN + 10];
    43 //找[1,n],[1,m]内互质的数的对数
    44 long long solve(int n, int m)
    45 {
    46     long long 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 += (long long)(sum[la] - sum[i - 1]) * (n / i) * (m / i);
    52     }
    53 
    54     return ans;
    55 }
    56 int main()
    57 {
    58     Moblus();
    59     sum[0] = 0;
    60     for (int i = 1; i <= MAXN; i++)
    61         sum[i] = sum[i - 1] + mu[i];
    62     int a, b, c, d, k;
    63     int T;
    64     scanf("%d%d%d%d", &a, &b, &c, &d);
    65    long long ans = solve(b, d) - solve((a - 1), d) - solve(b , (c - 1))
    66           + solve((a - 1), (c - 1));
    67         printf("%lld
    ", ans);
    68     
    69     return 0;
    70 }

    C - Contest Setting

    题意:给你n个数和选取k种不同难度的题,问有多少方案。

    思路:dp,dp[i][j]表示前i种选j个的方案数,先进行排序,算不同难度的个数存进数组,将其dp就是答案。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<vector>
     4 #include<map>
     5 #include<cstring>
     6 using namespace std;
     7 #define ll long long
     8 const int N = 1e3+5;
     9 const int mod = 998244353;
    10 ll dp[N][N];
    11 ll kind[N];
    12 ll a[N];
    13 int main()
    14 {
    15     ll i, j, k;
    16     ll n,  t,count=0;
    17     cin >> n >> k;
    18     for (i = 1; i <= n; i++)
    19     {
    20         cin >> a[i];
    21     }
    22     sort(a + 1, a + n + 1);
    23     ll cnt = 1, tot = 1;
    24     for (int i = 2; i <= n; i++)//
    25     {
    26         if (a[i] == a[i - 1])
    27         {
    28             cnt++;
    29         }
    30         else
    31         {
    32             kind[tot++] = cnt;
    33             cnt = 1;
    34         }
    35     }
    36     kind[tot] = cnt;//算不同种的个数
    37     memset(dp, 0, sizeof(dp));
    38     for (int i = 0; i <= 1000; i++)
    39     {
    40         dp[i][0] = 1;
    41     }
    42     for (i = 1; i <= tot; i++)//选第i种难度
    43     {
    44         for (j = 1; j <= k; j++)//选1-k个
    45         {
    46             dp[i][j] = ((dp[i - 1][j - 1] * kind[i] % mod) + dp[i - 1][j]) % mod;
    47         }
    48     }
    49     cout << dp[tot][k] << endl;
    50     
    51     
    52 
    53     
    54 }

    D - Count The Bits

     题意:给你整数k和b位数,问0-2^b-1被k整除的个数

    思路:数位dp,

    dp[i][j][0]表示前i位构成的数中对k取模为j的数的个数

    dp[i][j][1]表示前i位构成的数中对k取模为j的数中二进制中1的个数

     所求结果就是dp[b][0][1],即b位数能被k整除后二进制1的个数

    代码

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<vector>
     4 #include<map>
     5 #include<cstring>
     6 using namespace std;
     7 #define ll long long
     8 const int N = 1e3+5;
     9 const int mod = 1e9+9;
    10 ll dp[129][N][2];
    11 //dp[i][j][0]表示前i位构成的数中对k取模为j的数的个数
    12 //dp[i][j][1]表示前i位构成的数中对k取模为j的数中二进制中1的个数
    13 
    14 int main()
    15 {
    16     ll i, j, k;
    17     ll n,t,b;
    18     cin >> k >> b;
    19     dp[0][0][0] = 1;
    20     dp[0][0][1] = 0;
    21     for (i = 1; i <= b; i++)//前i位
    22     {
    23         for (j = 0; j < k; j++)
    24         {
    25             dp[i][j *2 % k][0] = (dp[i][(j *2) % k][0] + dp[i - 1][j][0]) % mod;
    26             dp[i][(j*2 + 1) % k][0] = (dp[i][(j*2 + 1) % k][0] + dp[i - 1][j][0]) % mod;
    27             
    28             dp[i][(j * 2) % k][1] = (dp[i][(j * 2) % k][1] + dp[i - 1][j][1]) % mod;
    29             dp[i][(j * 2 + 1) % k][1] = (dp[i][(j * 2 + 1) % k][1] + dp[i - 1][j][1] + dp[i - 1][j][0]) %mod;
    30         }
    31     }
    32     cout << dp[b][0][1];
    33   
    34     
    35     
    36 
    37     
    38 }

    E - Goat on a Rope

    题意:给你山羊(x,y),和矩形中心对称两端点(x1,y1)(x2,y2),求绳子I不到矩形的最大长度

    思路,点到矩形的最近距离

    代码

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<vector>
     4 #include<map>
     5 #include<cstring>
     6 using namespace std;
     7 #define ll long long
     8 const int N = 1e3+5;
     9 const int mod = 1e9+9;
    10 double cal(double x1, double y1, double x2, double y2)
    11 {
    12     return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
    13 }
    14 int main()
    15 {
    16     ll i, j, k;
    17     ll n, t, b;
    18     double ans = mod;
    19     double x, y, x1, x2, y2, y1;
    20     cin >> x >> y >> x1 >> y1 >> x2 >> y2;
    21     if (x >= min(x1, x2) && x <= max(x2, x1)) //在x1和x2之间,距离为与y的距离
    22         ans = min(abs(y1 - y), abs(y2 - y));
    23     else if (y >= min(y1, y2) && y <= max(y1, y2))//在y1和y2之间,距离为与x的距离 
    24         ans = min(abs(x - x1), abs(x - x2));
    25     else 
    26         ans = min(cal(x, y, x1, y1), min(cal(x, y, x2, y2), min(cal(x, y, x1, y2), cal(x, y, x2, y1))));//四端点的距离
    27     printf("%.3f
    ", ans);
    28     
    29 }

    F - Repeating Goldbachs

     题意:给你 一个数x(x≥4),将他拆分成两个质数,俩质数之差得到一个数再拆分,直至x<4,问多少步

    思路:打表质数,然后暴力即可

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<vector>
     4 #include<map>
     5 #include<cstring>
     6 using namespace std;
     7 #define ll long long
     8 const int N = 1e6+5;
     9 const int mod = 1e9+9;
    10 bool vis[N + 100];
    11 ll prime[N + 100];
    12 ll cnt = 0;
    13 void dabiao()
    14 {
    15     vis[0] = vis[1] = 1;
    16     for (int i = 2; i <= N; i++)
    17     {
    18         if (!vis[i])
    19         {
    20             prime[cnt++] = i;
    21             for (int j = i + i; j <= N; j += i)
    22                 vis[j] = 1;
    23         }
    24     }
    25 }
    26 int main()
    27 {
    28     ll i, j, k;
    29     ll n, t, b;
    30     dabiao();
    31     cin >> n;
    32     ll tmp = n,count=0;
    33     while (tmp >= 4)
    34     {
    35         for (j = 0; j < cnt; j++)
    36         {
    37             k = tmp - prime[j];
    38             if (vis[k] == 0)
    39             {
    40                 count++;
    41                 tmp = abs(k - prime[j]);
    42                 break;
    43             }
    44         }
    45     }
    46     cout << count << endl;
    47 }

    G - The Ending Point

    题意:给你起点(x,y)和一个字符串(上下左右),问终点

    思路:纯代入

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<vector>
     4 #include<map>
     5 #include<cstring>
     6 using namespace std;
     7 #define ll long long
     8 const int N = 2e6+25;
     9 const int mod = 1e9 + 7;
    10 ll a[N];
    11 int main()
    12 {
    13     ll i, j, k;
    14     ll n, m, t;
    15     ll x, y;
    16     string s;
    17     cin >> x >> y;
    18     cin >> s;
    19     for (i = 0; i < s.size(); i++)
    20     {
    21         if (s[i] == 'U')
    22             y++;
    23         else if (s[i] == 'D')
    24             y--;
    25         else if (s[i] == 'L')
    26             x--;
    27         else if (s[i] == 'R')
    28             x++;
    29     }
    30     cout << x << " " << y;
    31     
    32    
    33 
    34 }

    H - Weird Game

    题意:给你n个蛋糕,有两个操作可以选择:吃一个,吃半个,Mahmoud先吃,Bashar后吃,蛋糕剩一个的时候对手输,两个人玩的很好。

    思路:简单思路型的博弈论,当n为奇数时,达到权衡,Bashar跟着Mahmoud吃一样的量,达到胜利,相反n为偶数时,Mahmoud胜利。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<vector>
     4 #include<map>
     5 #include<cstring>
     6 using namespace std;
     7 #define ll long long
     8 const int N = 2e6+25;
     9 const int mod = 1e9 + 7;
    10 ll a[N];
    11 int main()
    12 {
    13     ll i, j, k;
    14     ll n, m, t;
    15     ll x, y;
    16     cin >> n;
    17     if(n%2==0)
    18         puts("Mahmoud");
    19     else
    20         puts("Bashar");
    21    
    22    
    23 
    24 }

    I - Time Limits

    题意:给你n个t毫秒时间和s倍,求以整数秒限制所有的t。

    思路:找最大的t,乘s倍,毫秒变整数秒向上取整(我直接+999省工作23333)

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<vector>
     4 #include<map>
     5 #include<cstring>
     6 using namespace std;
     7 #define ll long long
     8 const int N = 2e6+25;
     9 const int mod = 1e9 + 7;
    10 ll a[N];
    11 int main()
    12 {
    13     ll i, j, k;
    14     ll n, m, t;
    15     ll x, y,s;
    16     cin >> n>>s;
    17     for (i = 0; i < n; i++)
    18         cin >> a[i];
    19     sort(a, a + n);
    20     cout << (a[n - 1] * s + 999) / 1000 << endl;
    21    
    22    
    23 
    24 }
  • 相关阅读:
    [HNOI2002]营业额统计
    HDU 1374
    HDU 3345
    HDU 2089
    Graham扫描法
    Codeforces 1144D Deduction Queries 并查集
    Codeforces 916E Jamie and Tree 线段树
    Codeforces 1167F Scalar Queries 树状数组
    Codeforces 1167E Range Deleting
    Codeforces 749E Inversions After Shuffle 树状数组 + 数学期望
  • 原文地址:https://www.cnblogs.com/ch-hui/p/12780868.html
Copyright © 2011-2022 走看看