Contest2664 - 2021ACM俱乐部后备营个人训练赛第8场
别问为啥没有上一场的题解,问就是上一场俺划水去了(嘘)
问题 A: 打印图形VI
思路
有手就行(别锤我),有一点像第六场的 E题,找规律,行数等于n,列数从1到n分为前半段,后面的分为后半段,注意一下,行列之间(就是i,j)和字符ascii码的关系
代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
int i,j,n;
cin>>n;
for(j=1;j<=n;++j)
{
for(i=1;i<=n-j;++i)
cout<<" ";
for(i=1;i<=j;++i)
cout<<(char)('A'+j-i);
for(i=1;i<=j-1;++i)
cout<<(char)('A'+i);
cout<<endl;
}
return 0;
}
问题 B: 数列计算V
思路
找规律,分子的规律是第一个数到第二个数之间相差 1 ,第二个数到第三个数之间相差 2 ,分母的规律就是从 3 开始,依次递增2的奇数数列
#注:输出的时候注意是保留七位小数,俺最开始没长眼睛,保留了八位,WA了一次
代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
double a=2;
double b=3;
double temp=1;
double ans[15];
ans[0]=a/b;
for(int i=1;i<n;++i){
a += temp;
++temp;
b += 2;
ans[i] = a/b;
}
for(int i=0;i<n;++i)
printf("%.7lf\n",ans[i]);
sort(ans,ans+n);
for(int i=0;i<n-1;++i)
printf("%.7lf\n",ans[i]);
printf("%.7lf",ans[n-1]);
return 0;
}
问题 C: 报数
思路
简单模拟题,定义一个n的数组,模拟所有人面对教练的情况,一旦满足题意 是3.5.7的倍数,则改变该下标位置的模拟数,最后再遍历数组,输出并统计人数,最后再输出人数即可。
代码
#include <bits/stdc++.h>
using namespace std;
int flag[100]={0};
int main()
{
int n;
cin>>n;
int count=0;
for(int i=1;i<=n;++i)
{
if(i%3==0 || i%7==0 || i%5==0)
flag[i]=1;
}
for(int i=1;i<=n;++i)
{
if(flag[i]!=1){
cout<<i<<endl;
++count;
}
}
cout<<count;
return 0;
}
问题 D: 求素数III
思路
判断素数(我喜欢写成函数调用,从而判断),四位数拆分,统计个数,感觉最近几场做过很多这种类似的在范围内求符合条件的数
代码
#include <bits/stdc++.h>
using namespace std;
bool isPrime(int x)
{
for(int i=2;i<=sqrt(x);++i)
{
if(x%i==0)
return false;
}
return true;
}
int main()
{
int m,n,i;
cin>>m>>n;
int count=0;
int ge,shi,bai,qian;
int sum1,sum2;
for(i=m;i<=n;++i)
{
ge = i%10;
shi = (i%100)/10;
bai = (i/100)%10;
qian = i/1000;
sum1 = ge + shi;
sum2 = bai + qian;
if(isPrime(i) && sum1==sum2)
{
cout<<i<<endl;
++count;
}
}
cout<<count;
return 0;
}
问题 E: 求子串
某dalao教俺的,问题是他发现的(奉上我的膝盖)
思路
**法一:**使用 string 函数——substr(),不会的去看c++——string类基础详解。注意,输出的时候<<endl,改成<<"\n",前者会WA。我去了解了一下,认为可能是题目没有定义范围,如果是很长的字符串,范围过大,过多的使用endl会影响程序执行效率低下的因素之一,就是有点像大数据输入/输出流效率不如scanf/printfC++输入输出(自个拙见,欢迎指正)
**法二:**三个for循环,开字符数组,如果cin>>a;处,换成使用gets()函数会WA(dalao亲身经历),我了解了一下,说的是,“gets()函数存在一个严重的缺陷,这个缺陷就是:它不会检查数组是否能够装的下输入行,所以在C99标准中,已经不再建议使用gets()函数,而在C11中更是直接抛弃了这个函数”——C语言字符串读取函数 gets()与fgets()
代码
//法一:
#include<string>
#include<iostream>
using namespace std;
int main()
{
string a;
cin>>a;
long long m;
for(int i=0;i<a.size();i++)
for(int j=1;j<=a.size()-i;j++)
cout<<a.substr(i,j)<<'\n';
m=a.size();
m=m*(m+1)/2;
cout<<m;
return 0;
}
//法二:
#include<string.h>
#include<cstdio>
#include<iostream>
using namespace std;
char a[100000000]={0};
int main()
{
long long int m,j,sum=0;
cin>>a;
m=strlen(a);
for(int i=0;i<m;i++)
{
j=i;
{
for(int k=1;k<=m-i;k++)
{
j=i;
for(int l=1;l<=k;l++,j++)
printf("%c",a[j]);
printf("\n");
}
}
}sum=m*(m+1)/2;
printf("%lld",sum);
return 0;
}
问题 F: 计算图形的边长
思路
就是数学题,没啥好说的,大正方形的边长减小正方形的边长,再除以2,就是结果,注意一下保留两位小数就行
代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
double m,n;
cin>>m>>n;
double big = sqrt(m);
double small = sqrt(n);
double ans = (big-small)/2;
printf("%.2lf",ans);
return 0;
}
问题 G: 出租车费
思路
简单选择判断,小学数学,注意一下白天和夜晚的区别以及保留两位小数就行
代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
double x,ans=0;
int n;
cin>>x>>n;
if(0<x&&x<=3)
ans += 9;
else if(x>3&&x<=6)
{
if(n==1)
ans = 9+(x-3)*1.5;
else
ans = 9+(x-3)*1.75;
}
else if(x>6)
{
if(n==1)
ans = 13.5+(x-6)*2.25;
else
ans = 14.25+(x-6)*2.5;
}
printf("%.2lf",ans);
return 0;
}
问题 H: 门牌号
思路
直接暴力,循环,找到那个数跳出循环。
代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,s=0;
cin>>n;
for(int i=1; ;++i)
{
s+=i;
if(s>n && (s-n)%2==0)
{
cout<<(s-n)/2<<" "<<i;
break;
}
}
return 0;
}
问题 I: 上课时间
思路
数据我看着大,为了保险,我开了long long。分别计算周数(/7),和剩余天数(%7),对剩余天数做判断(我一开始因为这个WA了),剩余天数为6的时候,相当于读一周
代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
long long n,t,week,rest;
cin>>n;
week = n/7;
rest = n%7;
if(rest<=5)
t = (week*34+rest*6)*40;
else
t = (week+1)*34*40;
cout<<t;
return 0;
}
问题 J: 数链
思路
根据条件题意写循环即可,每循环一次统计链长,最终保留最长链长输出即可
代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
int a,b;
int i,j;
int l,maxl=-1;
cin>>a>>b;
for(i=a;i<=b;++i)
{
l=0;
j=i;
while(j!=1)
{
if(j%2==0)
j /= 2;
else
j = 3*j+1;
++l;
}
maxl=max(maxl,l);
}
cout<<maxl+1;
return 0;
}
问题 K: 读书活动
思路
注意一下输出提示“确保答案不超过n”,一开始没注意到,试运行的时候(就是把样例 改成了2 3)纳闷了一会儿。解题很简单,就是定义一个数组,存入每天他要忙的时间(u1s1,他可能不需要睡觉,这是题外话,嘿嘿),然后用他所需要的时间减去能看书的时间,一旦所需时间小于等于0,输出即可。
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,t;
int a[100];
cin>>n>>t;
for(int i=1;i<=n;++i)
cin>>a[i];
for(int i=1;i<=n;++i)
{
t -= (86400-a[i]);
if(t<=0)
{
cout<<i;
break;
}
}
return 0;
}
问题 L: 石头,剪刀,布
思路
我直接暴力做的,石头剪刀布的可能总共就六种,写出来之后,你会发现有两种和前面重复了,所以只有四种。定义一个长度为4的数组,统计四种情况下的次数,最后排序,输出最大的即可
代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,a,b;
int time[4];
int d=0,f=0,g=0,h=0;
cin>>n;
n++;
while(--n)
{
cin>>a>>b;
if(a==1&&b==3 || a==2&&b==1 || a==3&&b==2)
++d;
else if(a==1&&b==2 || a==2&&b==3 || a==3&&b==1)
++f;
else if(a==1&&b==2 || a==2&&b==3 ||a==3&&b==1)
++g;
else if(a==1&&b==3 || a==2&&b==1 ||a==3&&b==2)
++h;
}
time[0]=d;
time[1]=f;
time[2]=g;
time[3]=h;
sort(time,time+4);
cout<<time[3];
return 0;
}