热身赛题解
乎乎做核酸
https://ac.nowcoder.com/acm/contest/43657/A
A.乎乎做核酸
using namespace std;
int main(){
int n;
cin>>n;
printf("%d",n/2);
printf(":");
printf("%d",(n%2==0?0:30)); // 如果n%2==0,返回0,否则返回30
}
等待时间刚好是30。
B.chika和蜜柚
将信息保存到结构体,然后进行排序即可。需要自定义排序规则。
typedef long long ll;
const ll maxn=2e5+5;
using namespace std;
ll n,k;
struct Node{
ll a,b;
}nd[maxn];
bool cmp(Node &x,Node &y){
if(x.b!=y.b)
return x.b>y.b;
return x.a<y.a;
}
int main(){
cin>>n>>k;
for(int i=1;i<=n;i++)
scanf("%lld",&nd[i].a);
for(int i=1;i<=n;i++)
scanf("%lld",&nd[i].b);
sort(nd+1,nd+n+1,cmp);
ll aa=0,bb=0;
for(int i=1;i<=k;i++){
aa+=nd[i].a;
bb+=nd[i].b;
}
cout<<aa<<" "<<bb<<endl;
}
C.andy和购物
分别对价格和优惠进行排序。按照贪心的思路,价格贵的商品使用折扣大的优惠券最省钱。
typedef long long ll;
const ll maxn=1e3+5;
using namespace std;
int a[maxn];
double b[maxn];
int main(){
ll T;
cin>>T;
while(T--){
ll n;
cin>>n;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
scanf("%lf",&b[i]);
sort(a+1,a+n+1);
sort(b+1,b+n+1);
double ans=0;
for(int i=1;i<=n;i++){
ans+=a[i]*b[n+1-i];
}
printf("%.3f\n",ans);
}
}
D.咖啡店
先计算最多可以用多少张5元,然后拿总额-使用5元数量*5即可得到1元的使用数。
typedef long long ll;
using namespace std;
int main(){
ll a,b;
cin>>a>>b;
ll cost5=min(b/5,a);
cout<<cost5<<" "<<(b-cost5*5)<<endl;
}
E.Jay的小迷弟
读取字符串,如果有连续的Jay的话,单独保存到一个变量Jay中。剩下的J、a、y分别单独保存到变量J、a、y。 先不考虑*2的情况,我们得到的碎片数是J、a、y的最小值。现在开始考虑*2的情况,如果刚才得到碎片数为0,那么我们无论怎么*2都还是0,所以我们需要先消耗1个连续的Jay碎片使得碎片数变为1。接着直接*2即可
typedef long long ll;
const ll maxn=1e8+5;
const ll mod=1e9+7;
using namespace std;
char ch[maxn];
ll J,a,y; //表示除了连续Jay以外,剩下三个对应的数量
ll Jay; // 表示连续Jay的数量
int main(){
scanf("%s",ch);
for(int i=0;i<strlen(ch);i++){
if(i<strlen(ch)-2){
if(ch[i]=='J'&&ch[i+1]=='a'&&ch[i+2]=='y'){ // 如果找到连续的Jay,那么只保存到Jay,而不会再分别单独保存。
Jay++;
i+=2;
continue;
}
}
if(ch[i]=='J') J++;
else if(ch[i]=='a') a++;
else if(ch[i]=='y') y++;
}
ll ans=0;
ans=min(J,min(a,y));
if(ans==0&&Jay>0){
Jay--;ans++;
}
for(int i=1;i<=Jay;i++){
ans=2*ans%mod;
}
cout<<ans<<endl;
}
F.跳一跳
该题忘记标数据范围,非常抱歉。
for循环遍历原数组,如果当前超过可到达值,则结束,否则更新可到达值。
坑可能是在于可到达值一定要小于等于数组大小。
typedef long long ll;
const ll maxn=1e5+5;
using namespace std;
ll n;
ll a[maxn];
int main(){
cin>>n;
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
ll ans=1;
for(int i=1;i<=n;i++){
if(i>ans) break;
ans=max(ans,i+a[i]);
ans=min(ans,n);
}
cout<<ans<<endl;
}
G.序列2
遍历数组,维护一个当前值以及当前最大值。
坑点在于当前最大值可能是一个很小的数,因此初始化时需要注意设为极小的一个负数。
typedef long long ll;
const ll maxn=1e5+5;
using namespace std;
ll n;
ll a[maxn];
ll ans=-1e18;
int main(){
cin>>n;
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
ll now=0;
for(int i=1;i<=n;i++){
now+=a[i];
ans=max(ans,now);
}
cout<<ans<<endl;
}
H.爱吃草的羊驼
对三个边进行排序,最小的两边和需要大于第三边。符合三角形守则的话按照海伦公式输出结果即可。
typedef long long ll;
using namespace std;
int main(){
int a[5];
for(int i=1;i<=3;i++)
cin>>a[i];
sort(a+1,a+3+1);
if(a[1]+a[2]<=a[3]){
cout<<"Alpaca is hungry today!"<<endl;
return 0;
}
double p=(a[1]+a[2]+a[3])*1.0/2;
double ans=sqrt(p*(p-a[1])*(p-a[2])*(p-a[3]));
printf("Alpacas can eat %.3f of grass today!",ans);
}
I.乘和除
参考了牛客周赛的题目。没注意有两个以上0的情况,非常抱歉。
这道题只有四种答案。0,1,2,3
要注意0的存在。
- 如果原数组中有1,直接输出0
- 如果原数组中有两个数相同且均不为0,则把两数相除即可得到1,只需1步。
- 如果原数组中有两个数a、b的乘积为原数组中的任意一个数c,且这个数c不为0。那么我们先把a*b放入数组中,再将c除以这个数即可得到1。需要2步。
- 不符合以上的情况,我们只需找到任意两个不为0的数,将相乘后的结果再分两次除以原本的两数即可得到1。需要3步。
typedef long long ll;
using namespace std;
int num[8];
int main(){
for(int i=1;i<=4;i++)
cin>>num[i];
sort(num+1,num+4+1);
if(num[1]==1){
cout<<0<<endl;
return 0;
}
for(int i=1;i<=3;i++){
if(num[i]==num[i+1]&&num[i]!=0){
cout<<1<<endl;
return 0;
}
}
for(int i=1;i<=4;i++)
for(int j=i+1;j<=4;j++)
for(int k=1;k<=4;k++){
if(num[i]*num[j]==num[k]&&num[k]!=0){
cout<<2<<endl;
return 0;
}
}
cout<<3<<endl;
}
J.数组指定位置求和
对指定下表位置的数求和即可
typedef long long ll;
const ll maxn=1e2+5;
using namespace std;
ll n,m;
ll a[maxn];
ll b[maxn];
int main(){
cin>>n;
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
cin>>m;
for(int i=1;i<=m;i++)
scanf("%lld",&b[i]);
ll ans=0;
for(int i=1;i<=m;i++){
ans+=a[b[i]];
}
cout<<ans<<endl;
}