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 }
  • 相关阅读:
    15.Numpy之点乘、算术运算、切片、遍历和下标取值
    13.python-列表排序
    [Js-c++]c++中的指针、引用和数组名
    [Hadoop]Windows下用eclipse远程连接hdfs报错Connection denied解决方案
    [Java-JVM]Centos7编译openjdk7
    [Js-Java SE]Java中的Native关键字与JNI
    [Js-C++]C++中赋值表达式的结果
    [Js-C++].h文件与#include详解
    [Js-C++]C++中*&(指针引用)和*(指针)的区别
    [Js-Python]解决pip安装安装源速度慢的问题
  • 原文地址:https://www.cnblogs.com/ch-hui/p/12780868.html
Copyright © 2011-2022 走看看