Codeforces Round #452 (Div. 2)

来源:互联网 发布:森田淘宝旗舰店 编辑:程序博客网 时间:2024/06/13 21:36

传送门:http://codeforces.com/contest/899

899A - Splitting in Teams

题意:给你2*1e5的数,问最多能凑多少个3.(只有1和2)
思路:统计1和2的个数。先算2能匹配多少1.如果2的个数大于等于1的个数,那最大就是2的个数;如果2的个数小于1的个数,那最大的就是cnt2 + (cnt1 - cnt2) /3;

#include<bits/stdc++.h>using namespace std;int main (){    //yyy_3y    //freopen("1.in","r",stdin);    int n; cin >> n;    int cnt1 = 0;    int cnt2= 0;    for (int i = 1; i <= n; i++) {       int a; cin >> a;       if (a == 1) cnt1++;       else cnt2++;    }    int ans = 0;    if (cnt2 >= cnt1){        ans = cnt1;    }    else {        ans  = cnt2 + (cnt1 - cnt2) /3;    }    cout <<ans <<endl;}

899B - Months and Years

题意:给你一个小于的24的n,问你是否存以下n个数的连续的月份天数。
思路:赛后和别人交流了下,都选择了存3年,然后中间是闰年,这样就能包含所有的情况。直接暴力搜一遍就行。
我的话是选择记录29的个数,如果29的个数大于1肯定就是NO,然后把29变成28.
存3年搜一次。

#include<bits/stdc++.h>using namespace std;int a[100]= {0,31,28,31,30,31,30,31,31,30,31,30,31,31,28,31,30,31,30,31,31,30,31,30,31,31,28,31,30,31,30,31,31,30,31,30,31,31,28,31,30,31,30,31,31,30,31,30,31};int b[25];int main (){    //yyy_3y    //freopen("1.in","r",stdin);    int n; cin >> n;    int flag_2 = 0;    for (int i = 1; i <= n; i++){        cin >> b[i];        if (b[i] == 29) flag_2 ++;        if (b[i] == 29) b[i]--;    }    bool flag = 0;    for (int i = 1; i <= 24; i++){        int j;        int ii = i;        for (j = 1; j <= n; j++){            if ( a[ii++] != b[j]) break;        }        if (j == n + 1) {flag = 1; break;}    }    if (flag && flag_2 <= 1) cout << "YES" << endl;    else cout << "NO" << endl;}

899C - Dividing the numbers

题意:将集合{1,2,…,n}划分成两个集合,使得两个集合的元素之和的绝对差值最小。
思路:因为n才6e4,我做的很暴力,就求个和,(如果数偶数那差值肯定是0,如果是奇数,那肯定是1),求和之后我就从最后一个开始减,剪到小于自身就行。
标解的话应该分四类情况,分析,算一道数学题把。

#include<bits/stdc++.h>using namespace std;typedef long long ll;int a[100000];int main (){    //yyy_3y    //freopen("1.in","r",stdin);    ll t; cin >> t;    ll ans = (1 + t)*t/2;    if (ans & 1) cout << 1 <<endl;    else cout << 0 <<endl;    if ( t == 2){        cout << 1 << " " << 1 <<endl;        return 0;    }    ans = ans /2;    int cnt = 0;    while (1){            a[cnt++] = t;            ans = ans - t;            t--;            if (ans <= t){                if (ans == 0) break;                a[cnt++] = ans;                break;            }    }    cout << cnt;    for (int i = 0; i < cnt; i++){        cout << " " << a[i] ;    }    cout << endl;}

899D - Shovel Sale

题意:给你一个1e9的n,1–n,你可以使任意两个数字相加,输出使最后连续为9的位数最长的情况数量。
思路:很显然是一道规律题。
1-4 没有 9。
5-49:最后一位为9
500-4999:最后两位为9
…………
也就是说 5,50,500 …………是分界线。

进行构造和枚举。

1.对于一个五位数如 abcde我们考虑最高位,如果 a5,那么构造 A= x99999(即五个9),否则 A=x9999(四个9)
枚举 x = 0->8 .
分三类情况。
第一种: n A ,对答案的贡献度为 A/2;
第二种: n (A+1)/2 ,对答案的贡献度为0;
剩下的情况 对答案的贡献度为(2*n-A+1)/2

#include<bits/stdc++.h>using namespace std;#define ll long longint main (){    int n; cin >> n;    if (n < 5) cout << n*(n-1)/2 << endl;    else {        ll num = 5; int k;        for (int i = 1;  i <= 10; i++){            if (num > n){                k = i;                break;            }            num *= 10;        }        ll temp = 0; int cnt = 0;        for (int i = 1;i <= k -1; i++){            temp = temp*10 + 9;            cnt++;        }        ll ans = 0;        for (int i = 0; i <= 8; i++){            ll A  = temp + pow(10,cnt) * i;            if (A <= n) ans += A/2;            else if (n < (A+1)/2) break;            else ans += (2*n-A+1)/2;        }        cout << ans <<endl;    }}

899E - Segments Removal

题意:给定长度为N(200000),每次将序列中长度最大部分相等的区间删去(若有多种情况删去最左端的区间),问多少次操作可以将删完。
题解: 数据结构(。・・)ノ。 优先队列维护一下。
学习到了新的姿势,很开心(●ˇ∀ˇ●)。

#include<bits/stdc++.h>using namespace std;const int maxn = 2e5 + 10;priority_queue< pair <int,int>  > q1,del;int pre[maxn], nxt[maxn], num[maxn], col[maxn];int cnt = 0;int ans = 0;int main (){    int n; scanf("%d",&n);    for (int i = 1; i <= n; i++){        int x; scanf("%d",&x);        if (x == col[cnt]) num[cnt]++;        else col[++cnt] = x, num[cnt] = 1;    }    for (int i = 1; i <= cnt; i++){        pre[i] = i-1;        nxt[i] = i+1;        q1.push(make_pair(num[i],-i));    }    while (cnt){         while (!del.empty() && del.top() == q1.top()) q1.pop(), del.pop();         int tt = -q1.top().second; q1.pop();         int t1 = pre[tt];         int t2 = nxt[tt];         nxt[t1] = t2;         pre[t2] = t1;         if (t1 && col[t1] == col[t2]){  //合并            del.push(make_pair(num[t2],-t2));            del.push(make_pair(num[t1],-t1));            num[t1] += num[t2];            nxt[t1] = nxt[t2];            pre[nxt[t2]] = t1;            q1.push(make_pair(num[t1],-t1));            cnt--;         }         cnt--,ans++;    }    printf("%d\n",ans);    return 0;}/*1222 22 22 1 333 333 333 333 1 22 22 22*/
原创粉丝点击