A. Nearest Interesting Number
分析:随便写写就可以了。
#include "bits/stdc++.h"
using namespace std;
int getsum(int a){
int res = 0;
while(a){
res+=a%10;
a/=10;
}
return res;
}
int main(){
int n;
cin>>n;
while(getsum(n)%4!=0)n++;
cout<<n<<endl;
}
B. Equalize Prices
分析:找出最小值和最大值,两者的差小于等于K*2就OK,大于就输出-1。因为要求最大的,输出最小值+k就可以了。
#include "bits/stdc++.h"
using namespace std;
int a[104];
int main(){
int q;
cin>>q;
while(q--){
int n,k;
cin>>n>>k;
for (int i = 0; i < n; ++i) {
scanf("%d",&a[i]);
}
sort(a,a+n);
int maxi = a[n-1],mini=a[0];
if(maxi-mini>2 * k)puts("-1");
else printf("%d\n",mini+k);
}
}
C. Computer Game
分析:直接算一下就可以了,我这里写的不需要动脑子的二分。
#include "bits/stdc++.h"
using namespace std;
int a[104];
int main(){
int q;
cin>>q;
while(q--){
long long k,n,a,b;
scanf("%lld%lld%lld%lld",&k,&n,&a,&b);
long long ans = -1;
long long l = 0, r = n;
while(l<=r){
long long mid = (l+r)>>1;
if(mid*a+(n-mid)*b<k){
ans = mid;
l = mid+1;
}
else r=mid-1;
}
printf("%lld\n",ans);
}
}
D. Candy Box (easy version)
分析:记录一下每种糖果的个数,然后排个序,从最多的糖果开始选,如果有相等的,减1就可以了,这样可以保证size最大。
#include "bits/stdc++.h"
using namespace std;
int a[200004];
int main(){
int q;
cin>>q;
while(q--){
int n;
scanf("%d",&n);
for (int i = 0; i <= n; ++i) {
a[i]=0;
}
int x;
for (int i = 0; i < n; ++i) {
scanf("%d",&x);
a[x]++;
}
sort(a+1,a+1+n);
int ans = a[n];
for (int i = n-1; i >= 1; --i) {
if(a[i]<a[i+1])ans+=a[i];
else {
a[i]=a[i+1]-1;
if(a[i]<0)a[i]=0;
ans+=a[i];
}
}
printf("%d\n",ans);
}
}
E. Subsequences (easy version)
分析:直接找出所有子序列然后丢进set里,这是最暴力的想法,并且这里K只有100,所以是可行的。因为要求cost最小,所以从长度最长的开始,一个一个字符的删除,如果没有就丢进set和队列里,跑一遍就可以了。
#include "bits/stdc++.h"
using namespace std;
int a[200004];
int main(){
int n,k;
cin>>n>>k;
string s;
cin>>s;
set<string>se;
int ans = 0;
queue<string>q;
q.push(s);
se.insert(s);
while (!q.empty()){
if(se.size()==k)break;
s = q.front();q.pop();
for (int i = 0; i < s.size(); ++i) {
string ts = s;
ts.erase(i,1);
if(!se.count(ts)){
se.insert(ts);
ans += n- ts.size();
q.push(ts);
}
if(se.size()==k)break;
}
}
if(se.size()==k)printf("%d\n",ans);
else printf("-1");
}
F. Topforces Strikes Back
分析:首先枚举第一个数,然后对于这个数的答案就确定了,把与x冲突的去掉,把最大的作为y,再把与y冲突的去掉,剩下最大的作为z。然后我们就可以开始暴力剪枝了,因为是找最大的,然后从大到小排个序,然后写3个for+剪枝,由于某种原因,大概3个for是跑不满的,复杂度O(能过)。
#include "bits/stdc++.h"
using namespace std;
int a[200004];
bool cmp(int a,int b){return a>b;}
int main(){
int t;
cin>>t;
while (t--){
int n;
scanf("%d",&n);
for (int i = 0; i < n; ++i) {
scanf("%d",&a[i]);
}
sort(a,a+n,cmp);
n=unique(a,a+n)-a;
int ans = a[0];
for (int i = 0; i < n; ++i) {
bool ok = 0;
for (int j = i+1; j < n; ++j) {
if(a[i]%a[j]==0)continue;
ans = max(ans,a[i]+a[j]);
for (int k = j+1; k < n; ++k) {
if(a[i]%a[k]==0 || a[j]%a[k]==0)continue;
ans = max(ans,a[i]+a[j]+a[k]);
ok=1;
break;
}
if(ok)break;
}
}
printf("%d\n",ans);
}
}
G. Candy Box (hard version)
分析:D题plus。多了一个参数,相当于对两个关键字a,b排序。但是这里直接排序是不可以的,因为选了一种糖果后,如果还有其他种类的糖果的数量和它相等,那么需要将这些糖果的第一关键字减1,这里就乱序了。
那么我们可以开一个multiset,用来存当前数量的糖果的第二关键字,找出最大的一个erase掉,剩下的作为下次选糖果的备选。
#include "bits/stdc++.h"
using namespace std;
struct node
{
int num1,num2;
bool friend operator < (node a,node b){
if(a.num1==b.num1)return a.num2<b.num2;
else return a.num1<b.num1;
}
}a[200004];
int main(){
int q;
cin>>q;
while(q--) {
int n;
scanf("%d", &n);
int x, y;
for (int i = 0; i <= n; ++i) {
a[i].num1 = 0;
a[i].num2 = 0;
}
for (int i = 0; i < n; ++i) {
scanf("%d%d", &x, &y);
a[x].num1++;
a[x].num2 += y;
}
sort(a+1,a+1+n);
multiset<int>s;
int last = a[n].num1;
int ans1 = 0,ans2 = 0;
for (int i = n; i >= 0; --i) {
if(a[i].num1==last){
s.insert(a[i].num2);
}
else {
i++;
last--;
if(s.size()>0){
ans1 += last+1;
ans2 += min(last+1,*(--s.end()));
s.erase(--s.end());
}
else continue;
}
}
printf("%d %d\n",ans1,ans2);
}
}
H. Subsequences (hard version)
留坑。