AtCoder Beginner Contest 155

传送门

A - Poor

题意:如果三个数中只有且有两个一样的数,则被称为poor;请判断是不是poor;

思路:签到。

#include<bits/stdc++.h>
using namespace std;

int main(){
    int  a,b,c;
    cin>>a>>b>>c;
    if(a==b && a==c && b==c || a!=b && a!=c&& b!=c)cout<<"No"<<endl;
    else cout<<"Yes"<<endl;
    return 0;
}
Code

B - Papers, Please

题意:n个数,当其中的偶数都能被3或者5整除时 输出 APPROVED; 否则 输出 DENIED。

思路:签到。

#include<bits/stdc++.h>
using namespace std;
int n;
int main(){
    cin>> n ;
    for(int i=0;i<n;i++){
        int x ;cin>>x;
        if( x & 1 ) continue;
        else{
            if(x %3 != 0 && x%5!=0){
                cout<<"DENIED"<<endl;
                return 0;
            }
        }
    }
    cout<<"APPROVED"<<endl;
    return 0;
}
Code

C - Poll

题意:n个字符串,输出重复度最高的。

思路:签到。

#include<bits/stdc++.h>
using namespace std;
map<string,int> ma;

int main(){
    int n;
    cin >> n;
    int v =-1e8;
    for(int i=0;i<n;i++){
        string s;
        cin>>s;
        ma[s]++;
        v =max(v,ma[s]);
    }
    for(auto it:ma){
        if(it.second == v ) cout<<it.first<<endl;
    }
    return 0;
}
Code

D - Pairs

题意:n个数,a1, a2,…AN 有N(N - 1)/2种方法选择其中的两种并形成一对。如果我们计算这些对的乘积并按升序排序,那么这个列表中的第K个数字是多少.

思路:如果暴力配对,在排序, 那么O(N ^ 2logN)对于题目所给2<= N <= 2*105来说肯定会T。

看题目可知道是查找第k小/大的值kv,那么应该可以用二分O(logN)来解决。

如果二分的话。那么左右区间和判定条件怎么取?:

1.区间:题目所给 109Ai109 (1iN) ,那么两两相乘后的值在[-1018,1018] 内,long long 能存的下。

2.判定条件:对于在区间内任意给定的值x,遍历数组,统计配对后两两相乘后<=x 的数量(对的数量),如果这个数量>=k;则说明kv<=x;否则kv>x.

    对于kv的值来说,如果kv<0,那么应该是从数组中取1正1负;如果kv>0,那么应该是1正1正或1负1负。

那么由以上条件,可以发现这道题应该是可以做出来了。

#include<bits/stdc++.h>
using namespace std;
#define int long long
constexpr int mu = 1e9;
signed main(){
    int a[200000],n,k;
    cin>>n>>k;
    for(int i=0;i<n;i++) cin>>a[i];
    sort(a,a+n);
    int lb = -(mu*mu) ,ub =mu*mu;// 二分区间范围。
    while(ub - lb>1){
        int mid = (lb+ub)/2,cnt=0;//cnt 用来统计对的数量。
        for(int i=0;i<n;i++){
            if(a[i] < 0){
                cnt +=n- (lower_bound(a,a+n,(long double )mid/a[i])-a);
            }
            else if( a[i] >0){
                cnt += upper_bound(a,a+n,(long double)mid/a[i])-a;
            }
            else if( mid >= 0){
                // a[i]为0 且 任意值x >=0的话就有n对。
                cnt+=n;
            }
            // 去掉本身重复的。
            if( a[i] * a[i] <= mid) cnt--;
        }

        //判定条件,注意cnt是对数;
        (cnt>=2*k?ub:lb) = mid;
    }
    cout<<ub<<endl;
}
Code

E - Payment

题意:Atcode国有10100 +1种钞票,其金额分别为:1,10,102,103,...10(10^100).现在你要购买价值N元的物品,你必须支付x张钞票,总额>=N.

店员会退回给你m元有y张钞票。现在请你求min(x+y);

思路:从N的后往前扫描,如果当前位<5 或者 当前位为5的同时,前一位<5,答案加上当前位;否则答案加上10-当前位,前一位+1;最后判断最前一位存在,答案+1;

#include<bits/stdc++.h>
using namespace std;
char s[1000005];
int main(){
    scanf("%s",s+1);
    int cnt=0,l=strlen(s+1);
    for(int i=l;i>=1;i--){
        if(s[i]<'5'||(s[i]=='5'&&s[i-1]<'5'))cnt+=s[i]-'0';
        else{
            cnt+=10-(s[i]-'0');
            s[i-1]++;
        }
    }
    if(s[0])cnt++;
    printf("%d\n",cnt);
    return 0;
}
Code

F - Perils in Parallel

不是我力所能及的- -

猜你喜欢

转载自www.cnblogs.com/NukezY/p/12321272.html