目录
A - Nearest Interesting Number
A - Nearest Interesting Number
题意:
给定你一个数n,这个数字n一定满足它的数位和一定是3的倍数,现在给定一个完美数的定义:如果一个数字的数位和能被4整除,那么这个数字就是完美数,现在要求你算出最小的大于给定数字n的完美数
做法:
数位和的判断很简单,取余除10即可,找最小的完美数只需要在n+1的基础上进行循环判断即可,特判点:这个数字n本身的数位和即是4的倍数,所以对于n就得判断一次
WA了两发的我是FW!
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const ll mod=1e9+7;
const int maxn=1e5+10;
int t,n,m,k;
string s;
int main()
{
ios::sync_with_stdio(false);
int a;
while(cin>>a)
{
int tmp=0,n=a;
while(a>0)
{
tmp+=a%10;
a/=10;
}
if(tmp%4==0)
cout<<n<<endl;
else
{
for(int i=n+1;;i++)
{
int tt=i,ans=0;
while(tt>0)
ans+=tt%10,tt/=10;
if(ans%4==0)
{
cout<<i<<endl;
break;
}
}
}
}
return 0;
}
B - Equalize Prices
题意:
给定一个有n个数字的数组以及一个数字k,问能否找到一个数字B,B满足在数组中的任意一个数字±k的区间内,即B∈[a[i]-k,a[i]+k],如果不存在这样的数字B就输出-1
做法:
设想一下,要满足在一个数组内部所有数字的条件区间内,那么我们去两个极值,一个最大一个最小,这两个值算出来的值,不就是这个数组最大的范围区间的中间值,然后我们再判断这个值是否满足<=min+k&&>=max-k,然后因为题目中要求要是存在多个答案输出最大值,SO,min+k永远大于max-k,所以我们只需要把求出来的数字和min+k取个最大值就好了!
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const ll mod=1e9+7;
const int maxn=1e5+10;
int t,n,m,k;
string s;
int main()
{
ios::sync_with_stdio(false);
int t,k,a[110];
cin>>t;
while(t--)
{
cin>>n>>k;
for(int i=1;i<=n;i++)
cin>>a[i];
sort(a+1,a+n+1);
int tmp=(a[1]+a[n])/2;
if(a[1]+k>=tmp&&a[n]-k<=tmp)
cout<<max(tmp,a[1]+k)<<endl;
else
cout<<"-1"<<endl;
}
return 0;
}
C - Computer Game
题意:
你拥有一台笔记本,这台笔记本拥有k的电量,但是你还想玩n把游戏(再来亿把!!)你有两种选择:1、你可以不充电每玩一把游戏需要消耗a的电量。2、你可以边充电边玩,每玩一把需要消耗b的电量(别问为啥充电还掉电,问就是题目要求)问你最多能玩几把游戏(最多就是玩n把!这很重要的)
做法:
让我们来做一个比较离谱的算术
首先假设我们可以使用第一个方法玩x1次也就是x1*a,然后我们接着用第二个方法玩x2次也就是x2*b,这里为啥是分开算的呢,因为题目说明了a一定大于b,所以必然存在你玩了x1把之后剩余的电量还可以让你用第二个方法玩,因此设置两个变量。由此我们可以得出第一个表达式:x1*a+x2*b<k(不能=,因为第三个条件说明了k只要小于等于a,b中任意一个,就不可以再继续),接着a<b -> a-b<0,然后a-b<0代入x1*a+x2*b<k
我们就得到了x1*(a-b)+x2*b<k为了保持原式子的完整性,添加x1*b
SO,最后的表达式就变成了x1*(a-b)+(x2+x1)*b<k
此时题意里的强调就起到作用了,因为这里x1,x2是一种最优解的条件,那么意味着x1+x2=n(谁不想多玩点呀是吧)
所以式子再次变化x1*(a-b)+n*b<k -> x1<(k-n*b)/(a-b)
所以最优解就是这么个情况,注意C++语言除法默认向下取整,然而这里是<而不是<=因此,当右边能够整除时,这个数字-1才是我们的正确答案。以及一个特殊情况:当你用第二种方法去玩n把游戏时,电量根本不足以支撑你的任意一把游戏,你就得直接输出-1(别问怎么知道的,问就是被题目样例给坑了)
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const ll mod=1e9+7;
const int maxn=1e5+10;
string s;
int main()
{
ios::sync_with_stdio(false);
ll t,k,a,b,n;
cin>>t;
while(t--)
{
cin>>k>>n>>a>>b;
ll x=(k-n*b)/(a-b);
if((k-b*n)<=0)
{
cout<<-1<<endl;
continue;
}
if((k-n*b)%(a-b)==0)
x--;
cout<<min(x,n)<<endl;
}
return 0;
}
D - Candy Box (easy version)
题意:
你一共有q个糖果,这些糖果中有几种种类(种类数未知)当你要把这些糖果送给别人时,你可以取出同一种类的所有糖果(没说一定要取完!),但是当你第二次送给别人糖果时,你取出的这个种类的糖果数不能和你上一个送出的糖果数相同,问你最多能送出多少个糖果
做法:
排序加贪心,暴力跑就完了,从最大的个数开始送,送完一个就判断下一个值,要是这个值和刚刚的一样,那就少拿一个!物尽其用!
注意数组初始化的时候,不能全部初始化,会被卡死在第25个点
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const ll mod=1e9+7;
const int maxn=2e5+10;
string s;
int main()
{
ios::sync_with_stdio(false);
int t,n,num[maxn],maxx=0;
cin>>t;
while(t--)
{
maxx=0;
cin>>n;
for(int i=1;i<=n;i++)
num[i]=0;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
num[x]++;
maxx=max(x,maxx);
}
sort(num+1,num+maxx+1);
int tmp=num[maxx],ans=0;
for(int i=maxx;i>=1;i--)
{
if(num[i]<=0||tmp<=0)
break;
if(tmp>num[i])
tmp=num[i];
ans+=tmp;
tmp--;
}
cout<<ans<<endl;
}
return 0;
}