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; }
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; }
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; }
D - Pairs
题意:n个数,a1, a2,…AN 有N(N - 1)/2种方法选择其中的两种并形成一对。如果我们计算这些对的乘积并按升序排序,那么这个列表中的第K个数字是多少.
思路:如果暴力配对,在排序, 那么O(N ^ 2logN)对于题目所给2<= N <= 2*105来说肯定会T。
看题目可知道是查找第k小/大的值kv,那么应该可以用二分O(logN)来解决。
如果二分的话。那么左右区间和判定条件怎么取?:
1.区间:题目所给 −109≤Ai≤109 (1≤i≤N) ,那么两两相乘后的值在[-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; }
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; }
F - Perils in Parallel
不是我力所能及的- -