A:题目 1008:
[编程入门]成绩评定
#include <stdio.h>
int main(){
int score;
scanf("%d",&score);
if(score>=90) printf("A");
else if(score>=80) printf("B");
else if(score>=70) printf("C");
else if(score>=60) printf("D");
else printf("E");
}
本题考查简单的分支,只需按照题意写if,else即可
B:题目 1010:
[编程入门]利润计算
#include <stdio.h>
int main(){
int l;
scanf("%d",&l);
int bonus;
if(l<=100000) bonus=l*0.1;
else if(l<=200000) bonus=10000+(l-100000)*0.075;
else if(l<=400000) bonus=17500+(l-200000)*0.05;
else if(l<=600000) bonus=27500+(l-400000)*0.03;
else if(l<=1000000) bonus=33500+(l-600000)*0.015;
else bonus=39500+(l-1000000)*0.01;
printf("%d",bonus);
}
依旧考查分支的知识点,本题其实只是一个分段函数,由于题目要求输出和输出都是整数,所以也无需用浮点型定义变量。
C:题目 1141:
C语言训练-百钱百鸡问题
#include <stdio.h>
int main(){
for(int i=0;i<=20;i++){
for(int j=0;j<=34;j++){
for(int k=0;k<=100;k+=3){
if(i+j+k==100 && 5*i+3*j+k/3==100){
printf("cock=%d,hen=%d,chicken=%d\n",i,j,k);
}
}
}
}
}
方法一,最简单直白的三元一次方程穷举法,三层的循环嵌套,很简单可以得到我们想要的答案。
#include <stdio.h>
int main(){
for(int i=0;i<=20;i++){
for(int j=0;j<=34;j++){
int k=100-i-j;
if(i*5+j*3+k/3==100 && k%3==0) printf("cock=%d,hen=%d,chicken=%d\n",i,j,k);
}
}
}
方法二,在方法一的基础上减少了一层循环的嵌套,优化了算法
PS.你能在方法二的基础上继续优化吗(三元一次方程组,有一个已知量和两个方程式,求剩下的两个未知量,思考后可以尝试自己写一写,如果想不出来可以去看这个题解:百(N)钱百(N)鸡问题【四层解法递进】-题解(C++代码)-Dotcpp编程社区)
D:题目 1018:
[编程入门]有规律的数列求和
#include <stdio.h>
int main(){
float sum=0.0;
float i=2,j=1,temp;
int n;
scanf("%d",&n);
for(int r=0;r<n;r++){
sum+=i/j;
temp=i;
i+=j;
j=temp;
}
printf("%.2f",sum);
return 0;
}
题解:本题需要找规律,会发现每个分数的分子是前一个数的分子分母和,分母是前一个数的分子,所以我们需要单独定义一个temp变量来当做中间变量存放变之前的i,这里i和j我们也用浮点型定义,因为如果是整形的话,下面的循环里,sum会被类型转换,导致最后结果错误。
E:题目 1022:
[编程入门]筛选N以内的素数
#include <stdio.h>
#include <math.h>
int main(){
int n;
scanf("%d",&n);
for(int i=2;i<=n;i++){
int isprime=1;//用于记录是否是素数
for(int j=sqrt(i);j>=2;j--){
if(i%j==0){
isprime=0;
break;
}
}
if(isprime) printf("%d\n",i);//如果是素数的话就输出
}
}
最简单的暴力算法,两层循环的嵌套,但我们只需要判断2到i的平方根内有没有能被i整除的数即可判断i是否是一个素数(本题也可以优化(欧拉筛),但需要用到数组,故不在此赘述)
F:题目 2692:
蓝桥杯2022年第十三届省赛真题-质因数个数
面对这题,可能大部分的思路首先还是简单粗暴的暴力算法,用两层循环判断素数,然后再判断这个素数是否是n的约数,提交,然后会发现,时间超限,这可能是各位同学第一次遇见会时间超限的题吧,那么我们就需要优化算法。首先我们可能会想到,先判断这个数是不是n的约数,再判断这个数是不是素数,可能会好一点,确实相比较于前一个方法,会好很多,但是还是会超时。那么最优解是什么样的呢,最优解用到了欧拉筛的思想。
#include <stdio.h>
int main(){
long long int n,ans=0;
scanf("%ld",&n);
for(long long int i=2;i<=n/i;i++){
if(n%i==0){
ans++;
while(n%i==0) n/=i;
}
}
if(n>1) ans++;
printf("%ld",ans);
}
我们知道,任何合数都一定有比这个数小的质因数,所以我们从2开始,每遇见一个能整除n的i,就令n循环除等于i,这样就可以排除所有以质数i为因数的n的合数因数(多读几遍),此时,当我们在循环中再次遇见可以整除n(此时n已经循环除尽前一个i)的i,这个i就一定是质数。
那么,为什么在for循环里的限制条件是i<=n/i呢,我们假设一个j,令i*j=n,那么j就等于n/i,当i>j时,因式的形式就只是当i<=j时的乘法交换律变形罢了,所以我们只需判断在i<=j范围内,有无能整除n的因子i, 所以限制条件便是i<=n/i
最后,为什么当n>1时ans++,当循环结束后,已经排除了n的所有合数因数,此时的n本身就是原n的一个因数(一开始输入的n)只要n>1,那么这个n就绝对是原n的一个质数因数,所以此时ans++
感兴趣的同学可以去搜索欧拉筛,并了解一下
本题可以把代码复制到自己的编译器上,自己设置断点debug一下,有助于理解
G:题目 2701:
蓝桥杯2022年第十三届决赛真题-取模(C/C++/Java组)
#include <stdio.h>
int main(){
int t;
scanf("%d",&t);
while(t--){
int n,m,judge=0;
scanf("%d %d",&n,&m);
for(int y=1;y<=m;y++){
for(int x=1;x<y;x++){
if(n%x==n%y){
judge=1;
break;
}
}
if(judge==1) break;
}
if(judge)printf("Yes\n");
else printf("No\n");
}
}
这题竟然暴力就可以做出来(没错我也很震惊)但需要注意,如果外层循环是x,内层循环是y的话,照样还是过不了的,judge=1时,还要跳出函数,否则还是会超时,在暴力的基础上简单优化,这题就可以过。
以下是由江夏学长友情赞助的本题最优解(毕竟感觉这题不应该用暴力解法不卡时间复杂度),运用了中国剩余定理,感兴趣的同学可以研究一下
#include<stdio.h>
void solve(){
int n, m; scanf("%d %d", &n, &m);
int is = 0;
m = m > 13? 13:m;
for(int i=2; i<=m; i++){
if( n%i != i-1){
is = 1;
break;
}
}
if(is) printf("Yes\n");
else printf("No\n");
}
int main(){
int t; scanf("%d", &t);
while(t--) solve();
return 0;
}