zoukankan      html  css  js  c++  java
  • Codeforces Round #521 (Div. 3)

    题目链接:http://codeforces.com/contest/1077

    A.Frog Jumping

    解题思路:作差再判断最后是否还要向右跳一次即可。

    AC代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 LL T,a,b,k;
     5 int main(){
     6     while(cin>>T){
     7         while(T--){
     8             cin>>a>>b>>k;
     9             cout<<(a-b)*(k/2)+(k%2?a:0)<<endl;
    10         }
    11     }
    12     return 0;
    13 }
    B.Disturbed People

    解题思路:题意已说得很清楚了,只要找到满足a[i-1]==1&&a[i]==0&&a[i+1]==1,那么就关掉第i-1和第i+1间房间的灯(其状态值改为0),若满足条件--->i+=3,表示当前的灯已熄灭,只需站到第i+3间房间继续检查即可。

    AC代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 int n,cnt,a[105];
     5 int main(){
     6     while(cin>>n){
     7         cnt=0;
     8         for(int i=0;i<n;++i)cin>>a[i];
     9         for(int i=1;i<n-1;){
    10             if(a[i-1]&&!a[i]&&a[i+1])cnt++,i+=3;
    11             else i++;
    12         }
    13         cout<<cnt<<endl;
    14     }
    15     return 0;
    16 }
    C.Good Array

    解题思路:统计所有元素之和:sum,然后枚举每个元素,令tmp=(sum-a[i])>>1表示原数组删去a[i]后剩余元素之和的一半,由"好的数组"定义可知,如果(sum-a[i])为奇数,则剩下的元素肯定不能分成相等的两部分;否则只需检查tmp是否在剩下的元素当中,若是则归纳答案!

    AC代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 const int maxn=2e5+5;
     5 int n,k,b[maxn];LL a[maxn],sum,tmp;map<LL,int> mp;
     6 int main(){
     7     while(~scanf("%d",&n)){
     8         sum=0,k=0;mp.clear();
     9         for(int i=1;i<=n;++i)scanf("%lld",&a[i]),sum+=a[i],mp[a[i]]++;///要用map或一维数组记录每个数字出现的次数,不能用set容器
    10         for(int i=1;i<=n;++i){
    11             if((sum-a[i])&1LL)continue;///奇数则跳过
    12             tmp=(sum-a[i])>>1;
    13             mp[a[i]]--;///先删去该元素
    14             if(mp[tmp])b[k++]=i;
    15             mp[a[i]]++;///再添加该元素
    16         }
    17         printf("%d
    ",k);
    18         if(!k)puts("");
    19         for(int i=0;i<k;++i)printf("%d%c",b[i],(i==k-1)?'
    ':' ');
    20     }
    21     return 0;
    22 }
    D.Cutting Out

    解题思路:题目要求找出k个元素组成的集合t,使得每次删去集合s中包含t集合中的k个元素,并且最大化删除的次数,典型的二分查找答案!先统计每个元素出现的次数cnt_i,再通过二分查找最大化删除的次数z,二分条件为∑cnt_i/z≥k,如果为True,则向右找更大的删除次数,否则向左找较小的删除次数,最后每个元素被挑选的个数就为cnt_i/z',简单输出集合t中的k个元素即可。

    AC代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include <map>
     4 #include <vector>
     5 using namespace std;
     6 typedef long long LL;
     7 int n, k, x, l, r, mid, t;
     8 map<int, int> mp;
     9 vector<int> ans, cnt;
    10 bool check(int z){
    11     int sum = 0;
    12     for (auto num : cnt)sum += num / z;
    13     return sum >= k;
    14 }
    15 int main(){
    16     while (~scanf("%d%d", &n, &k)){
    17         mp.clear(), ans.clear(), cnt.clear(); l = 1, r = n;
    18         for (int i = 0; i < n; ++i)scanf("%d", &x), mp[x]++;
    19         for (auto y : mp)cnt.push_back(y.second);///保存对应数字出现的次数
    20         while (l <= r){///二分查找要切的最大次数
    21             mid = (l + r) >> 1;
    22             if (check(mid))l = mid + 1;///最大化往右边找
    23             else r = mid - 1;
    24         }
    25         for (auto u : mp){
    26             t = u.second / r;
    27             while (t--)ans.push_back(u.first);///第i个元素一次需要取t个
    28         }
    29         for (int i = 0; i < k; ++i)printf("%d%c", ans[i], i == k - 1 ? '
    ' : ' ');
    30     }
    31     return 0;
    32 }
  • 相关阅读:
    poj 1850/poj 1496
    poj 1035
    poj 3252
    hdoj 1013
    poj 2965
    poj 1844
    poj 2309
    蓝桥杯比赛回来后计划。。。
    山大实训第二周感想
    hadoop——Map/Reduce中combiner的使用
  • 原文地址:https://www.cnblogs.com/acgoto/p/9974594.html
Copyright © 2011-2022 走看看