首页 > 代码库 > Codeforces Round #402 (Div. 2)

Codeforces Round #402 (Div. 2)

补的,不过都是自己做的。

A。Pupils Redistribution 【数学】

题意:交换A、B两数组中的元素,使得两组数组含1、2、3、4、5元素的个数相等。

做法:统计A组中1~5的个数,B组中减去。统计正数/2、负数/2绝对值,求两者最大值。数学问题,自己推一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <bits/stdc++.h>
#define  MEM(a,b) memset(a,b,sizeof(a))
using namespace std;
int main(){
    int n, a[110], b[110], sco[10];
    scanf("%d",&n);
    MEM(sco,0);
    for(int i = 0; i < n; i++){
        scanf("%d", a + i);
        sco[a[i]] ++;
    }
    for(int i = 0; i < n; i++){
        scanf("%d", b + i);
        sco[b[i]] --;
    }
    int sum1 = 0, sum2 = 0;;
    for(int i = 1; i <= 5; i++){
        if(sco[i] % 2 != 0){
            puts("-1");
            return 0;
        }
        else if(sco[i] > 0){
            sum1 += sco[i] >> 1;
        }
        else if(sco[i] < 0){
            sum2 -= sco[i] >> 1;
        }
    }
    printf("%d\n", max(sum1,sum2) );
}
B。Weird Rounding 【贪心】
题意:给定N、K两个数,求最少去除N中几个数可使得被10^K整除。
做法:1.当N==0时输出0;
          2.如果0够用(K个0)的话,从右往左删除不是0的数;
          3.如果0不够用的话,把N删剩下一个0,那么就整除了,也就sum - 1。(题目保证有结果,所以至少有一个0)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <bits/stdc++.h>
#define  MEM(a,b) memset(a,b,sizeof(a))
using namespace std;
int main(){
    int n, k;
    cin >> n >> k;
    int ans = 0, sum = 0;
    if(n == 0){
        cout << 0 << endl;
        return 0;
    }
    while(n){
        if(n % 10 == 0) k--;
        else ans++;
        if(k == 0) break;
        n /= 10;
        sum ++;
    }
    if(k == 0) cout << ans << endl;
    else cout << sum - 1 << endl;
}

C。Dishonest Sellers【贪心】

题意:你需要买N个商品,分别给出今天的价格和下一周的价格,你今天必须买K个。求最少花钱方案。

做法:根据A[i]-B[i]的结果sort一下(也就是今天优惠程度越高排越前)。然后从左往右先买K个A,剩下的买A、B中便宜的。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <bits/stdc++.h>
using namespace std;
struct Node{
    int a,b;
}node[200010];
bool cmp(const Node &x, const Node &y){
    return x.a - x.b < y.a - y.b;
}
int main(){
    int n, k;
    cin >> n >> k;
    for(int i = 0; i < n; i++) cin >> node[i].a;
    for(int i = 0; i < n; i++) cin >> node[i].b;
    sort(node, node + n, cmp);
    int sum = 0, i;
    for(i = 0; i < k; i++) sum += node[i].a;
    for(i; i < n; i++){
        if(node[i].a < node[i].b) sum += node[i].a;
        else break;
    }
    for(i; i < n; i++) sum += node[i].b;
    cout << sum << endl;
}
D。String Game【二分结果+judge字符串模拟】
题意:妹妹她会按照数组a的元素值a[i],依次删除字符串T第a[i]个元素。哥哥要得到字符串P,求最多让妹妹删除几个字符。
做法:二分结果,求的右界,所以是 mid = (low + high + 1) / 2,bool返回true则low = mid,false则high = mid - 1;
     judge函数 模拟下,O(n)复杂度
BTW,如果求左界,mid = (low + high) / 2,bool返回true则high=mid,false则low=mid+1;
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <bits/stdc++.h>
using namespace std;
char a[200020], b[200020];
int num[200020];
int len;
bool judge(int x)
{
    bool vis[200020];
    memset(vis,false,sizeof(vis));
    for(int i = x + 1; i <= len; i++) vis[num[i]] = true;
    int idx = 1;
    for(int i = 1; i <= strlen(b+1); i++)
    {
        while(vis[idx] == false || a[idx] != b[i]){
            idx++;
            if(idx > len){
                return false;
            }
        }
        idx++;
    }
    return true;
}
int main(){
 
    scanf("%s%s",a+1,b+1);
    len = strlen(a+1);
    for(int i = 1; i <= len; i++) scanf("%d", num + i);
    int low = 0, high = len - 1;
    while(low < high){
        int mid = (low + high + 1) / 2;
        if(judge(mid)) low = mid;
        else high = mid - 1;
    }
    printf("%d\n",low);
}

Codeforces Round #402 (Div. 2)