Codeforces Round #402 (Div. 2)

来源:互联网 发布:国外人工智能发展现状 编辑:程序博客网 时间:2024/05/14 01:38

A - Pupils Redistribution(water)

题意:给出两组数,将两组中的数交换,使相同的数在两组内个数相同,求最小交换次数

#include <bits/stdc++.h>using namespace std;const int INF = 0x3f3f3f3f;const int maxn = 100 + 5;typedef long long LL;typedef pair<int, int>pii;int n;int cnt[10];int a[105], b[105];int solve(){    int ans = 0;    for(int i = 1; i <= 5; i++)    {        if(abs(cnt[i]) % 2 != 0) return -1;        ans += abs(cnt[i]) / 2;    }    if(ans % 2 == 1)    return  -1;    return ans / 2;}int main(){    cin >> n;    for(int i = 0; i < n; i++)  cin >> a[i], cnt[a[i]]++;    for(int i = 0; i < n; i++)  cin >> b[i], cnt[b[i]]--;    cout << solve() << endl;    return 0;}


 

B - Weird Rounding(water)

题意:给你一个数n,一个数k,问你至少删掉几个数能够让n整除10的k次

#include <bits/stdc++.h>using namespace std;const int INF = 0x3f3f3f3f;const int maxn = 100 + 5;typedef long long LL;typedef pair<int, int>pii;int main(){    LL n, k;    cin >> n >> k;    if(n == 0)    {        puts("0");    }    else    {        int cnt = 0, del = 0;        LL nn = n;        while(n && cnt < k)        {            int temp = n % 10;            if(temp == 0)   cnt++;            else del ++;            n /= 10;        }        int len = 0; while(nn){len++, nn /= 10;}        if(cnt < k) printf("%d", len - 1);        else printf("%d\n", del);    }    return 0;}


C - Dishonest Sellers(贪心)

题意:要买N个东西,打折是ai元,不打折是bi元,且ai有可能大于bi。打折的时候至少要买k个。买N个东西至少花多少钱。

思路:很容易想到的贪心啊,就是ai里至少要买k个,那么肯定是a[i]-b[i]最小的k个先买了,然后有个坑,就是至少,那么如果a[i]-b[i]还有小于0的,肯定也是在ai里头就买掉了。

#include <bits/stdc++.h>using namespace std;const int INF = 0x3f3f3f3f;const int maxn = 3e5 + 5;typedef long long LL;typedef pair<int, int>pii;int a[maxn], b[maxn];int main(){    int n, k;    scanf("%d%d", &n, &k);    for(int i = 0; i < n; i++)  scanf("%d", &a[i]);    for(int i = 0; i < n; i++)  scanf("%d", &b[i]);    priority_queue<pii, vector<pii>, greater<pii>>que;    for(int i = 0; i < n; i++)    {        que.push({a[i] - b[i], i});//挑一个a[i]-b[i]尽可能小的    }    LL sum = 0;    while(k--)    {        pii p = que.top();que.pop();        sum += a[p.second];    }    while(que.size())    {        pii p = que.top();que.pop();        if(p.first < 0) sum += a[p.second];        else sum += b[p.second];    }    cout << sum << endl;    return 0;}


D - String Game(二分)

题意:

思路:简单二分,就是二分答案x,然后针对这个x,进行模拟,得到两个字符串,问题就转化成在能否由字符串a删除一部分得到字符串b的经典问题了。O(n)复杂度即可,大白书第一章练习题。再次复习一下,求尽可能大的时候的二分是left+right+1  >> 1,求尽可能小的时候的二分是left+right >> 1。

#include <bits/stdc++.h>using namespace std;const int INF = 0x3f3f3f3f;const int maxn = 200000 + 5;typedef long long LL;typedef pair<int, int>pii;int len, lenp;int a[maxn], vis[maxn];char t[maxn], p[maxn], w[maxn];bool judge(int x){    memset(vis, 0, sizeof(vis));    for(int i = 0; i < x; i++)    {        vis[a[i] - 1] = 1;    }    int lenw = 0;    for(int i = 0; i < len; i++)    {        if(vis[i] == 0)   w[lenw++] = t[i];    }    //能否从w中删除得到p    if(lenw < lenp) return false;    int cnt = 0;    for(int i = 0; i < lenw; i++)    {        if(p[cnt] == w[i])  cnt++;    }    return cnt == lenp;}int main(){    scanf("%s", t);    scanf("%s", p);    len = strlen(t);    lenp = strlen(p);    for(int i = 0; i < len; i++)    scanf("%d", &a[i]);    int left = 0, right = len;    while(right > left)    {        int mid = (left + right + 1) >> 1;        if(judge(mid))        {            left = mid;        }        else        {            right = mid - 1;        }    }    cout << left << endl;    return 0;}







0 0
原创粉丝点击