【C/C++】蓝桥杯算法必刷题(一)目标ICPC铜/蓝桥杯国一

目录

前言

该题单中第一类考点:输入输出

1001、这是一道签到题

1005、乘法表

1006、KiKi学程序设计基础

1007、疫情死亡率

该题单中第二类考点:思维题

1002、排列式

1018、开学?

 1019、helloworld

 1022、整数的十位

 1023、反向输出一个四位数

 1020、a+b

1035、KiKi的最高分

1036、组队比赛

 1038、长方体

1039、 使徒袭来

 1040、白兔的分身术

 1041、纸牌

 1044、旅游观光

该题单中第三类考点:数论

1046、挂科

 1047、得不到的爱情

该题单中第四类考点:贪心 

 1043、珂朵莉的假动态仙人掌 

尾言


前言

本文概述:蓝桥杯、ICPC等算法竞赛入门题单之顺序结构,整理出了该题单中值得一做的题目并附带考点和详细的解题思路。

作者介绍:作者本人是一名人工智能炼丹师,目前在实验室主要研究的方向为生成式模型,对其它方向也略有了解,希望能够在CSDN这个平台上与同样爱好人工智能的小伙伴交流分享,一起进步。谢谢大家鸭~~~

 如果你觉得这篇文章对您有帮助,麻烦点赞、收藏或者评论一下,这是对作者工作的肯定和鼓励。  

 题解文章汇总

入门部分(有一定基础的可以直接跳到初级部分)

【C/C++】蓝桥杯算法必刷题(一)标签:思维、数论、贪心

【C/C++】蓝桥杯算法必刷题(二)标签:思维

【C/C++】蓝桥杯算法必刷题(三)标签:二进制、二进制枚举、思维

待更新~~~

初级部分

待更新~~~

高级部分

待更新~~~

题目传送门:算法必刷题(一)

该题单只用做如下题目即可(精选):

1001、这是一道签到题

1005、乘法表

1006、KiKi学程序设计基础

1007、疫情死亡率

1002、排列式

1018、开学?

1019、helloworld

1022、整数的十位

1023、反向输出一个四位数

1020、a+b

1035、KiKi的最高分

1036、组队比赛

1038、长方体

1039、 使徒袭来

1040、白兔的分身术

1041、纸牌

1044、旅游观光

1046、挂科

1047、得不到的爱情

1043、珂朵莉的假动态仙人掌

尽量先独立完成哦~~~~

将该算法入门所有题单系统刷完,将拥有蓝桥杯B组国一、ICPC/CCPC铜牌的水平

该题单中第一类考点:输入输出

以下是值得一做的题目,已经剔除知识点重复的题目

以上这些题考点均为:C/C++基础输入输出及格式控制

#include #万能头文件

1001、这是一道签到题 

 1001考察的是换行符\n

#include
int main(){
    printf("zhe\nshi\nyi\ndao\nqian\ndao\nti");
    return 0;
}

1005、乘法表 

1005考察的是控制格式输出 %nd为输出int型整数,其中n为输出多少位整数,不足的位数用空格填充

#include
int main(){
    for(int i=1;i<=9;i++){
        for(int j=1;j<=i;j++){
            printf("%d*%d=%2d ",j,i,(i*j));
        }
        printf("\n");
    }
    return 0;
}

1006、KiKi学程序设计基础 

 1006考察 " 和\n等格式符的输出

#include
int main(){
    printf("printf(\"Hello world!\\n\");\n");
    printf("cout << \"Hello world!\" << endl;");
}

1007、疫情死亡率 

 1007考察 %的输出 和浮点数的输出 PS:涉及浮点数的运算建议都先提前将有关运算的变量都转为浮点型或者直接定义为浮点型,避免出现各种错误。

#include
using namespace std;
int main(){
    double a=0;
    double b=0;
    cin>>a>>b;
    printf("%.3lf%%",(b/a*100));
    return 0;
}

该题单中第二类考点:思维题

1002、排列式

这题为思维题+全排列

思维:

1位数*1位数肯定无法凑出来9位数字,1*2,1*3同理

1位数*4位数可以凑出来9位数

然后继续推下去,发现2位数*3位数可以凑出9位数

接下来只需要知道1-9的9位数全排列分别套入这两种情况中,如果乘数相乘等于结果则输出

然后我们发现,需要乘出来的结果是小的排前面,同样结果第一位乘数小的排前面。

那么我们就有两种思路:

一是一开始就给结果的高位上最小值,然后依次减少,第一位乘数同理,这样枚举的时候,结果和第一位乘数都是从小到大变化的。(如果一开始的结果不是最小值、最大值,枚举的结果一定不是递增、递减的关系。)

二是先将结果储存起来,然后进行完排序后输出结果。

#include
using namespace std;
int main(){
    int n[9]={1,2,3,4,5,6,7,8,9};
    do{
        int x1=n[4];
        int y1=n[5]+10*n[6]+100*n[7]+1000*n[8];
        int sum1=n[3]+10*n[2]+100*n[1]+1000*n[0];
        int x2=n[5]+10*n[4];
        int y2=n[6]+10*n[7]+100*n[8];
        int sum2=n[3]+10*n[2]+100*n[1]+1000*n[0];
        if(sum1==x1*y1){
            printf("%d = %d x %d\n",sum1,x1,y1);
        }
        if(sum2==x2*y2){
            printf("%d = %d x %d\n",sum2,x2,y2);
        }
    }while(next_permutation(n,n+9));
    return 0;
    
}

1018、开学?

思维,两个数字相加除以7,余数即为星期几。需要注意的是余数为0的情况是星期日(7)

#include
using namespace std;
int main(){
    int a=0;
    int b=0;
    int t=0;
    cin>>a>>b;
    t=(a+b)%7;
    if (t==0){
        cout<<7<

 1019、helloworld

思维,c/c++中字符是以ascll码的形式存储的,对字符进行加减本质就是对ascll进行加减

字符数组会有\0做为字符串结束标志,如果用sizeof求长度的话要减一,建议使用strlen,求出的长度就是实际的字符长度。

#include
using namespace std;
int main(){
    char str[]="hello world";
    int l=0;
    l = strlen(str);
    for(int i=0;i

 1022、整数的十位

思维,有两种思路。一种是直接将它以字符串的形式直接读进数组,然后用下标就可以取出对应位数的数字了。第二种是纯数学方法,我们用一个数字%10会得到最低位数上的数字,比如123%10=3,因此想要获得十位上的数字只要将十位变成最低位数就行了,也就是int (123/10) 这样2就是最低位了,同理百位就/100然后取整

#include
using namespace std;
int main(){
    int a=0;
    cin>>a;
    cout<<(int(a/10))%10<

 1023、反向输出一个四位数

思维题,想要做出来非常简单,但是我们要通过这道题去学习两种反转数组/字符串的方法,这对以后我们做其它的题,或者锻炼我们的思维有很大的帮助。

第一种方法,第一项和最后一项互换;第二项与倒数第二项互换;第三项与倒数第三项互换;以此类推,直到换到中间。

第二种方法 C++ STL库中的 reverse函数

 char* 这个返回类型的意思是返回这个字符数组的地址,有了数组的地址肯定就能知道该地址上全部的数据了,所以这就是返回一个数组的意思。

#include
using namespace std;

char* Reverse(char a[]){
    char temp;
    int l=0;
    l=strlen(a);
    for(int i=0;i>str;
    a = Reverse(str);
    printf("%s",a);
    
}

 第二种方法,是直接修改原数组,然后参数是你要反转数组的区域的首地址和尾地址,比如你只想反转前三个数字,就是reverse(&str[0],&str[2])

#include
using namespace std;
int main(){
    char str[100]="";
    cin>>str;
    int l = strlen(str);
    reverse(&str[0],&str[l]);
    cout<

 1020、a+b

进制转化,模板题。一定要把进制转化模板背得滚瓜烂熟非常非常非常重要!!!!!!,必须得熟练掌握 n进制转m进制 n进制转10进制 10进制转n进制。

转换流程

不要觉得这题这样做太麻烦,关键是练习基本功和思维

#include
using namespace std;

string ten_to_N(long long a,int n){
    string str;
    while(a){
        long long x = a%n;
        a/=n;
        if(x<10){
            str +=x+'0';
        }
        else{
            str +=x-10+'a';
        }
    }
    reverse(str.begin(),str.end());
    return str;
}


int main(){
    long long a=0;
    long long b=0;
    cin>>a>>b;
    long long c=a+b;
    string str1 = ten_to_N(c,16);
    cout<

其它进制转换模板见传送门:进制转换模板 

1035、KiKi的最高分

水题中的水题,遍历一遍数组就能出结果。但是这里可以给你们介绍两个内置函数

 第一个是直接求数组指定范围内的最大/最小值

#include
using namespace std;

int main(){
    int a[10]={0};
    for(int i=0;i<3;i++){
        cin>>a[i];
    }
    int max=*max_element(a,a+3);
//     int min=*min_element(a,a+3);
    cout<

第二个是求数组指定范围内第一个最大/最小值的下标 

#include
using namespace std;

int main(){
    int a[10]={0};
    for(int i=0;i<3;i++){
        cin>>a[i];
    }
    int max_p=max_element(a,a+3)-a;
//     int min_p=min_element(a,a+3)-a;
    cout<

 容器的类似实现请看传送门:容器最大最小值函数

1036、组队比赛

思维,最大和最小一组,中间的为一组。这就是差距最小的组合,注意题目给我们的数据是乱序的,我们需要自己先排个序

 需要注意加上个绝对值,例如 1 2 2 2 这种情况

#include
using namespace std;

int main(){
    int n[4]={0};
    for(int i=0;i<4;i++){
        cin>>n[i];
    }
    sort(n,n+4);
    cout<<(abs(n[3]+n[0]-n[2]-n[1]));
    return 0;
}

 1038、长方体

思维、假设长宽高分别为a,b,c,则三个面的面积则分别为ab,bc,ac。我们怎么知道单条边呢。我们已知ab,bc,ac的值所以我们可以将它们相乘 abc*abc=定值。然后我们在分别除于ab,bc,ac则就可以得到三边了。

 第一次提交也Wa了,因为开的数据类型是int爆了,最坏的情况下 ab*bc*ac=1e15

#include
using namespace std;

int main(){
    long long ab=0;
    long long bc=0;
    long long ac=0;
    cin>>ab>>bc>>ac;
    long long abc=sqrt(ab*bc*ac);
    cout<<(abc/bc+abc/ac+abc/ab)*4<

1039、 使徒袭来

思维、积为定值时,若乘数都是整值则乘数都相等时,所有乘数之和最小

 这题需要注意的点,一是涉及浮点运算,故开double的数据类型 然后pow里面的1/3必须是浮点数,这个涉及自动类型转换 如果是1/3结果就是0 如果是1.0/3结果是0.3333333

#include
using namespace std;

int main(){
    double n=0;
    cin>>n;
    double a=pow(n,1.0/3);
    printf("%.3lf",a*3);
    return 0;
}

 1040、白兔的分身术

思维、根据题目列出关系式p^k=n,我们可以知道当n为定值的时候,因为k是指数,所以变大一点点就会导致p变小非常多,导致得不偿失,所以我们要使k尽可能小,然后最小的正整数就是1所以k就为1 关系式就变成了p=n 然后答案就很明显了。

#include
using namespace std;

int main(){
    long long n=0;
    cin>>n;
    cout<

 1041、纸牌

思维、设两张牌分别为a,b则第一次 a-n/2 第二次 b-(a-n/2) 第三次 (a-n/2)-(b-(a-n/2))时,a+b最小

 注意,最终的结果我们要向上取整,例如n=3的情况。

#include
using namespace std;

int main(){
    long long n=0;
    cin>>n;
    cout<<(n+1)/2<

 1044、旅游观光

思维、我们对说明进行一下分析:

首先是1->10的票价是(1+10)mod(10+1) 即票价为0

然后是10->2的票价是(10+2)mod(10+1)即票价为1

2->9、9->3、3->8、8->4、4->7、7->5、5->6、的票价分别是0、1、0、1、0、1、0

最后的总票价为4

所以,我们要尽可能多的构造 i+j=n+1的情况才能让票价最小,那么怎么构造呢。还是仔细看例子

1->10 2->9 3->8 ..... 发现了吧,第一组是首尾两个数字,第二组是次首和次尾,依次类推,因此当为n时,共有n-1张票,我们的票价就是(n-1)/2 

#include
using namespace std;

int main(){
    long long n=0;
    cin>>n;
    cout<<(n-1)/2;
}

该题单中第三类考点:数论

1046、挂科

数论、容斥原理与鸽巢原理 高中数学不解释

#include
using namespace std;

int main(){
    long long n=0;
    long long x=0;
    long long y=0;
    cin>>n>>x>>y;
    long long Min=0;
    long long Max=0;
    if(x+y<=n){
        Min=0;
    }
    else{
        Min=x+y-n;
    }
    Max=min(x,y);
    cout<

 1047、得不到的爱情

数论、塞瓦维斯特定理:对于形如ax+by=c式子,当a,b均大于1且a,b互为素数(最大公约数==1 or gcd(a,b)==1),满足方程无整数解的c的最大值为a*b-a-b

#include
using namespace std;

int main(){
    long long n,m;
    cin>>n>>m;
    cout<

该题单中第四类考点:贪心 

 1043、珂朵莉的假动态仙人掌 

贪心,全局最优的结果刚好可以拆分成每天最优,想让送的天数最多,那就是每天送的礼物最少就是每天送1本,但是相邻两天的本子个数不同,所以下一天最少送的本子数是2本,所以我们可以将2天(3本)做为一个单位,然后用n%3 如果余数为0就是能送n/3*2天,否者就只可以送n/3*2+1天。

#include
using namespace std;

int main(){
    long long n=0;
    cin>>n;
    if((n%3)==0){
        cout<

尾言

 如果您觉得这篇文章对您有帮忙,请点赞、收藏。您的点赞是对作者工作的肯定和鼓励,这对作者来说真的非常重要。如果您对文章内容有任何疑惑和建议,欢迎在评论区里面进行评论,我将第一时间进行回复。 

你可能感兴趣的:(算法入门必刷题单,c++,蓝桥杯,算法,数据结构,c语言)