zoukankan      html  css  js  c++  java
  • Codeforces Round #610 (Div. 2) 前5题题解

    Codeforces Round #610 (Div. 2) 前5题题解

    感觉这场比赛质量不错,出题人真的良心,样例数据给那么详细。

    这次我还第一次遇到了ILE(Idleness limit exceeded),原来fflushu(stdout)是每次输出后都要用的……

    比赛传送门

    A.Temporarily unavailable

    题目大意:有一条数轴,要从a点跑到b点,在c点的地方有网络,覆盖范围为半径为r的圆。问在多少时间有网路覆盖。

    因为是在数轴上的,所以有网路覆盖的地方就是(c - r,c + r),那么只要减一下就好,注意可能有些区域在跑的地方的外面。

    代码如下:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstring>
     5 #include <vector>
     6 #define rep(x, l, r) for(int x = l; x <= r; x++)
     7 #define repd(x, r, l) for(int x = r; x >= l; x--)
     8 #define clr(x, y) memset(x, y, sizeof(x))
     9 #define all(x) x.begin(), x.end()
    10 #define pb push_back
    11 #define mp make_pair
    12 #define MAXN
    13 #define fi first
    14 #define se second
    15 #define SZ(x) ((int)x.size())
    16 using namespace std;
    17 typedef long long ll;
    18 typedef vector<int> vi;
    19 typedef pair<int, int> pii;
    20 const int INF = 1 << 30;
    21 const int p = 1000000009;
    22 int lowbit(int x){ return x & (-x);}
    23 int fast_power(int a, int b){ int x; for(x = 1; b; b >>= 1){ if(b & 1) x = 1ll * x * a % p; a = 1ll * a * a % p;} return x % p;}
    24 
    25 int main(){
    26     int t;
    27     scanf("%d", &t);
    28     while(t--){
    29         int a, b, c, r;
    30         scanf("%d%d%d%d", &a, &b, &c, &r);
    31         printf("%d
    ", max(a, b) - min(a, b) - max(0, min(max(a, b), c + r) - max(min(a, b), c - r)));
    32     }
    33     return 0;
    34 }
    View Code

    B1.K for the Price of One(Easy Version)

    题目大意:有n个商品,每个商品价值为 ai ,现在有一个活动优惠,买一个物品可以选择k - 1个价值小于等于该它的物品免费获得(要么一个也不选,要么一定要选k - 1个),求k个硬币一共能买多少物品。在该题中k = 2。

    不难发现,买下来的的物品一定是最便宜的那几个。我们设状态 dp[i][0/1] 表示第i个物品选还是不选的最小花费。

    若是不选了i个,i - 1肯定要选,若是选了第i个,第i - 1个可以选可以不选,得到转移方程。

    最后找到最大的 dp[i][1] 小于等于p即为答案。

    代码如下:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstring>
     5 #include <vector>
     6 #define rep(x, l, r) for(int x = l; x <= r; x++)
     7 #define repd(x, r, l) for(int x = r; x >= l; x--)
     8 #define clr(x, y) memset(x, y, sizeof(x))
     9 #define all(x) x.begin(), x.end()
    10 #define pb push_back
    11 #define mp make_pair
    12 #define MAXN 200005
    13 #define fi first
    14 #define se second
    15 #define SZ(x) ((int)x.size())
    16 using namespace std;
    17 typedef long long ll;
    18 typedef vector<int> vi;
    19 typedef pair<int, int> pii;
    20 const int INF = 1 << 30;
    21 const int p = 1000000009;
    22 int lowbit(int x){ return x & (-x);}
    23 int fast_power(int a, int b){ int x; for(x = 1; b; b >>= 1){ if(b & 1) x = 1ll * x * a % p; a = 1ll * a * a % p;} return x % p;}
    24 
    25 int a[MAXN], dp[MAXN][2];
    26 
    27 int main(){
    28     int t;
    29     scanf("%d", &t);
    30     rep(times, 1, t){
    31         int n, p, k;
    32         scanf("%d%d%d", &n, &p, &k);
    33         rep(i, 1, n) scanf("%d", &a[i]);
    34         sort(a + 1, a + n + 1);
    35         rep(i, 1, n){
    36             dp[i][0] = dp[i - 1][1];
    37             dp[i][1] = min(dp[i - 1][0], dp[i - 1][1]) + a[i];
    38         }
    39         int ans = 0;
    40         rep(i, 1, n)
    41             if(dp[i][1] <= p) ans = i;
    42             else break;
    43         printf("%d
    ", ans);
    44     }
    45     return 0;
    46 }
    View Code

    B2.K for the Price of One(Hard Version)

    题目大意:有n个商品,每个商品价值为  ai  现在有一个活动优惠,买一个物品可以选择k - 1个价值小于等于该它的物品免费获得(要么一个也不选,要么一定要选k - 1个),求k个硬币一共能买多少物品。在该题中k <= n。

    做完这道题发现B1写复杂了,其实这两题代码一样的……

    主要思路就是贪心+递推。

    很显然,若是买了第i个物品,价值小于它的必然要选(不要白不要,而且肯定要最贵的)。

    那么我们就得出了递推式 f[i] = f[i - k] + a[i] ,但是注意若i小于等于k,需要的花费为前i个物品的总和。

    代码如下:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstring>
     5 #include <vector>
     6 #define rep(x, l, r) for(int x = l; x <= r; x++)
     7 #define repd(x, r, l) for(int x = r; x >= l; x--)
     8 #define clr(x, y) memset(x, y, sizeof(x))
     9 #define all(x) x.begin(), x.end()
    10 #define pb push_back
    11 #define mp make_pair
    12 #define MAXN 200005
    13 #define fi first
    14 #define se second
    15 #define SZ(x) ((int)x.size())
    16 using namespace std;
    17 typedef long long ll;
    18 typedef vector<int> vi;
    19 typedef pair<int, int> pii;
    20 const int INF = 1 << 30;
    21 const int p = 1000000009;
    22 int lowbit(int x){ return x & (-x);}
    23 int fast_power(int a, int b){ int x; for(x = 1; b; b >>= 1){ if(b & 1) x = 1ll * x * a % p; a = 1ll * a * a % p;} return x % p;}
    24 
    25 int a[MAXN], dp[MAXN];
    26 
    27 int main(){
    28     int t;
    29     scanf("%d", &t);
    30     rep(times, 1, t){
    31         int n, p, k;
    32         scanf("%d%d%d", &n, &p, &k);
    33         rep(i, 1, n) scanf("%d", &a[i]);
    34         sort(a + 1, a + n + 1);
    35         int ans = 0;
    36         rep(i, 1, n){
    37             if(i < k) dp[i] = dp[i - 1] + a[i];
    38             else dp[i] = dp[i - k] + a[i];
    39         }
    40         rep(i, 1, n)
    41             if(dp[i] <= p) ans = i;
    42         printf("%d
    ", ans);
    43     }
    44     return 0;
    45 }
    View Code

    C.Petya and Exam

    题目大意:Petya将会参加一场考试,这场考试从时间点0开始,到T结束。考试中有n道题,分为两种,简单(需要花a时间做完)的题和困难(需要花b时间做完)的题(a <= b),即在时间点x开始做这道题,将会在x+a或x+b时间点完成。现在每道题会在时间点 ti 变成必须完成,Petya可以在0 ~ T任意一个时间点离开,若离开时有必须要完成的题目没有完成,他将会得到0分,否则会得到他完成的题目的分数。求他最大能得到的分数。

    我们可以得到一个贪心策略,若是在时间点i离开且i+1没有必须要完成的题目,那么在i点离开肯定不如在i+1时间点离开,所以我们只要比较所有 ti - 1 离开能得到的最大分数。

    只需要将时间点 ti 排序以后,即可记录下当时需要完成的题目和所要花的时间

    另外,对于每一个点,在完成所有需要完成的题目后,肯定要先去做简单的题目,若还有时间再去做困难的题目。

    代码如下

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstring>
     5 #include <vector>
     6 #define rep(x, l, r) for(int x = l; x <= r; x++)
     7 #define repd(x, r, l) for(int x = r; x >= l; x--)
     8 #define clr(x, y) memset(x, y, sizeof(x))
     9 #define all(x) x.begin(), x.end()
    10 #define pb push_back
    11 #define mp make_pair
    12 #define MAXN 200005
    13 #define fi first
    14 #define se second
    15 #define SZ(x) ((int)x.size())
    16 using namespace std;
    17 typedef long long ll;
    18 typedef vector<int> vi;
    19 typedef pair<int, int> pii;
    20 const int INF = 1 << 30;
    21 const int p = 1000000009;
    22 int lowbit(int x){ return x & (-x);}
    23 int fast_power(int a, int b){ int x; for(x = 1; b; b >>= 1){ if(b & 1) x = 1ll * x * a % p; a = 1ll * a * a % p;} return x % p;}
    24 
    25 pii pro[MAXN];
    26 int num[MAXN];
    27 
    28 int main(){
    29     int q;
    30     scanf("%d", &q);
    31     rep(times, 1, q){
    32         int n, T, a, b;
    33         scanf("%d%d%d%d", &n, &T, &a, &b);
    34         int tot0 = 0, tot1 = 0;
    35         rep(i, 1, n){
    36             scanf("%d", &num[i]);
    37             if(!num[i]) tot0++;
    38             else tot1++;
    39         }
    40         rep(i, 1, n){
    41             int x;
    42             scanf("%d", &x);
    43             pro[i] = mp(x, num[i]);
    44         }
    45         pro[++n] = mp(T + 1, 0);
    46         sort(pro + 1, pro + n + 1);
    47         int ans = 0, sta0 = 0, sta1 = 0;
    48         rep(i, 1, n){
    49             if(sta0 > T) break;
    50             if(pro[i - 1].fi != pro[i].fi){
    51                 int tim = pro[i].fi - 1;
    52                 tim -= sta0;
    53                 int res = sta1;
    54                 if(tim >= 0){
    55                     res += min(tim / a, tot0);
    56                     tim -= min(tim / a, tot0) * a;
    57                     res += min(tim / b, tot1);
    58                     ans = max(ans, res);
    59                 }
    60             }
    61             if(pro[i].se){
    62                 tot1--;
    63                 sta0 += b;
    64             }
    65             else{
    66                 tot0--;
    67                 sta0 += a;
    68             }
    69             sta1++;
    70         }
    71         printf("%d
    ", ans);
    72     }
    73     return 0;
    74 }
    View Code

    D.Enchanted Artifact

    题目大意:本题为交互题。有一个字符串s,只由字符'a'和'b'组成。每次你可以询问一个字符串,它会返回这两个字符串的编辑距离。为一个字符串经过修改,删除或插入操作得到另一个字符串,两个字符串编辑距离的定义为最小的操作次数,若返回值为0,那么就是字符串s。让你在n + 2操作内得出字符串s(n为字符串s的长度,未知)。

    人生中第一次对交互题有想法,但是是错的想法……

    一开始我认为输入'a'和'b',若是原字符串有'a'字符,那么返回的是长度n - 1,否则返回的是长度n,那么原字符串的长度n为返回两值的最小值+1。

    然后询问一个由1个'b'和 n - 1 个'a'组成的字符串,共有n种,返回的数一定是字符串中b的个数加1或减1,即该位是否为b,然后因为在询问n +1次后一定要给出字符串s,那么通过前n - 1推出最后一位是否是'b'。

    这个方法看上去没问题,但是发现了一组反例。

    s字符串为"baaab"

    询问的字符串为"aaaba"

    根据我的思路返回数应该是3,即字符串中不相同的个数,但是这个数据返回了2。

    只需要在首位插入'b',在末位插入'a'即可。

    然后我就傻掉了,去看了下题解。

    发现题解的思路是先输入300个'a',再输入300个'b',返回的数分别是300 - 'a'的个数以及300 - 'b'的个数,那么就得到了原字符串中'a'和'b'的个数以及字符串的长度。然后将答案串设为全'a',对于每一位将该位为'b',如果返回值小于当前的编辑长度(一开始全'a'的编辑长度就是字符'b'的个数),那么答案的这一位一定是'b'。但是最多询问n + 2次,那么最后一位也只能靠前面答案推出,即若当前编辑长度为1那么最后一位是'b',否则为'a'。

    乍一看这个题解思路和我的差不多,但是它不会像我的代码一样出现反例。

    为什么呢,因为对于第i位改为'b'时,它前面的字符已经是和字符串s相同了,而我这个反例的最少的编辑操作是将'b'前面的一段往后移动一位,再插入一位比只修改操作要优。但是由于前i - 1位已经相同了就不会有这种操作,那么后面就一定是修改操作。

    另外题解中一开始求长度的操作也是优于我的方法的,我的方法很难得出是插入操作还是存在修改操作,所以在n = 2的情况下很难直接得出答案,而题解直接得出了字符串s中'a'和'b'的个数,可以直接给出。

    代码如下:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstring>
     5 #include <vector>
     6 #define rep(x, l, r) for(int x = l; x <= r; x++)
     7 #define repd(x, r, l) for(int x = r; x >= l; x--)
     8 #define clr(x, y) memset(x, y, sizeof(x))
     9 #define all(x) x.begin(), x.end()
    10 #define pb push_back
    11 #define mp make_pair
    12 #define MAXN
    13 #define fi first
    14 #define se second
    15 #define SZ(x) ((int)x.size())
    16 using namespace std;
    17 typedef long long ll;
    18 typedef vector<int> vi;
    19 typedef pair<int, int> pii;
    20 const int INF = 1 << 30;
    21 const int p = 1000000009;
    22 int lowbit(int x){ return x & (-x);}
    23 int fast_power(int a, int b){ int x; for(x = 1; b; b >>= 1){ if(b & 1) x = 1ll * x * a % p; a = 1ll * a * a % p;} return x % p;}
    24 
    25 int judge(string st){
    26     puts(st.c_str());
    27     fflush(stdout);
    28     int ans;
    29     scanf("%d", &ans);
    30     if(!ans) exit(0);
    31     return ans;
    32 }
    33 
    34 int main(){
    35     int n = 300;
    36     int lena = n - judge(string(n, 'a')),
    37         lenb = n - judge(string(n, 'b'));
    38     int len = lena + lenb;
    39     string ans = string(len, 'a');
    40     int res = lenb;
    41     rep(i, 0, len - 2){
    42         ans[i] = 'b';
    43         int s = judge(ans);
    44         if(s > res) ans[i] = 'a';
    45         else res = s;
    46     }
    47     if(res) ans[len - 1] = 'b';
    48     judge(ans);
    49     return 0;
    50 }
    View Code
  • 相关阅读:
    C# 文本,图片 与 Base64的相互转换
    vue3.x 中的自定义组件及使用
    vue 的TodoList 小Demo
    vue中的条件渲染 v-show、v-if、v-else、v-else-if
    vue 使用$refs获取表单内容及v-model双向数据绑定
    python-异常处理&操作数据库&网络编程
    python-接口开发
    python-数据库&邮件
    python-函数和模块
    python-函数&list&dic&集合&文件读取
  • 原文地址:https://www.cnblogs.com/nblyz2003/p/12173579.html
Copyright © 2011-2022 走看看