Codeforces Round #681(Div.2) 题解(A-C)

题意:给出一个数n,构造出一个数组,使得不存在任何两个数之间互质或者互成倍数关系,每个数的范围是1~4*n

解题思路:通过观察可知,构造出2*n,2*n+2...4*n-2这样的数列即可符合要求

代码:

#include<iostream>
#include<algorithm>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<set>
#include<stack>
#include<map>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define mul_mod(a,b,c) a=(a*b)%mod
#define add_mod(a,b,c) a=(a+b)%mod
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const int maxm=5e5+10;
const int inf=0x3f3f3f3f;
int q,n; 
int main()
{
    scanf("%d",&q);
    while(q--){
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            printf("%d ",2*n+i*2);
        }
        printf("\n");
    }
    return 0;
}
View Code

 

题意:给出一个字符串,1表示有地雷,0表示没地雷,要求把所有地雷引爆所需要的的最低费用,a表示引爆一个地雷需要的费用,引爆一个地雷可以把相连的所有地雷一起引爆,b表示埋下一个地雷需要的费用

解题思路:贪心。从地雷出现的第一个位置开始遍历,遍历到下一个连续的地雷区或者字符串末尾,从将所有空白区域埋上地雷和额外引爆一次所花费的费用中取最小值加到答案中。(代码实现比较丑陋,不喜勿喷)

代码:

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<vector>
 4 #include<cstdio>
 5 #include<cstring>
 6 #include<cmath>
 7 #include<queue>
 8 #include<set>
 9 #include<stack>
10 #include<map>
11 #define pb push_back
12 #define mp make_pair
13 #define fi first
14 #define se second
15 #define mul_mod(a,b,c) a=(a*b)%mod
16 #define add_mod(a,b,c) a=(a+b)%mod
17 using namespace std;
18 typedef long long ll;
19 const int maxn = 2e5 + 10;
20 const int maxm = 5e5 + 10;
21 const int inf = 0x3f3f3f3f;
22 int q, a, b;
23 char s[maxn];
24 int main()
25 {
26     scanf("%d", &q);
27     while (q--) {
28         scanf("%d%d", &a, &b);
29         scanf("%s", s);
30         int ans = 0;
31         int len = strlen(s);
32         int beg = 0, ed = len - 1;
33         while (s[beg] == '0' && beg < len) beg++;
34         while (s[ed] == '0' && ed >= 0) ed--;
35         ans = a;
36         if (beg >= len) {
37             printf("0\n");
38             continue;
39         }
40         int p = beg;
41         while (p <= ed) {
42             
43             while (s[p] == '1' && p <= ed) p++;
44             int count = 0;
45             while (s[p] == '0' && p <= ed) p++, count++;
46             ans += min(a, count * b);
47         }
48         printf("%d\n", ans);
49     }
50     return 0;
51 }
View Code

 

 题意:分别一共有n个菜品,对于第i个菜品可以选择等到a[i]的时间餐厅自己送过来或者自己花费b[i]的时间亲自己去餐厅取,求n道菜品到家的最短时间。

解题思路:将所有菜品按照a[i]从小到大排序,算出b[i]的后缀和,suf[i]表示从第i个菜品全部自己去取所需要的时间,因为已经排过序了,所以a[i]就可以表示前i道菜品餐厅送来所需要的时间,从这两个时间中取最大值即为当前方案所需要的时间,整体遍历一遍即可得出答案,时间复杂度O(n)

代码:

#include<iostream>
#include<algorithm>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<set>
#include<stack>
#include<map>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define mul_mod(a,b,c) a=(a*b)%mod
#define add_mod(a,b,c) a=(a+b)%mod
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const int maxm=5e5+10;
const int inf=0x3f3f3f3f;
int q,n;
pair<ll,ll> a[maxn]; 
ll suf[maxn];
int main()
{
    scanf("%d",&q);
    while(q--){
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%lld",&a[i].fi);
        for(int i=1;i<=n;i++) scanf("%lld",&a[i].se);
        sort(a+1,a+1+n);
        memset(suf,0,sizeof(suf));
        for(int i=n;i>=0;i--) suf[i]=suf[i+1]+a[i].se;
        ll ans=2e14;
        for(int i=0;i<=n;i++){
            ans=min(ans,max(a[i].fi,suf[i+1]));
            
        }
        printf("%lld\n",ans);
    }
    return 0;
}
View Code

 

posted @ 2020-11-11 00:30  陌默丶  阅读(94)  评论(0)    收藏  举报