CSP算法题基础(1)

CSP算法题基础

  1. C++程序里面会添加许多头文件,头文件的格式一般是

    1763#include<头文件名>
    

    我们先接触这两个头文件cstdio和iostream,其中cstdio包含了两个函数printf输出函数和scanf输入函数;第二个头文件是iostream,主要包含了cin,cout,endl三个函数。

    using namespace std;  // 命令空间指的是 保证在同一命名空间里面,变量名不冲突即可。不同的命名空间里面的变量名是可以相同,因为命名空间不同。命名空间一般我们都是使用在较大项目中,这种项目的变量一般比较多,有使用价值,算法比赛中,意义不大。
    

    bool false/true 1Byte

    char 1Byte

    int范围是\([-2^{31},2^{31}-1]\) 一共是\(2^{32}\)个数。十进制下这些数是-2147483648 to 2147483648。 4Byte

    float 1.23,1(整数也可以被浮点数表示)。此外,还支持科学计数法,比如1.23e2就是\(1.23*10^2\) ,float的精度比较低,通常只有6-7位有效数字 4Byte

    double 双精度浮点数,它的精度比较高,通常是15-16位有效数字 8Byte

    long long (int的扩展版) 它的表示范围是\([-2^{63},2^{63}-1]\) 8Byte

    long double(double的扩展版),它的精度是18-19位 16Byte

    常用编辑器显示float和double类型一般是6位,不足6位补0,超过6位,四舍五入截断。

    使用经验:最好使用int,然后使用double,最后使用float

    注意数值整数也有类型:

    long long m =13123123234LL;  //对,必须对整数添加后缀进行说明该整数是longlong类型整数
    long long m = 13123123234;    //错,整数数值类型和变量类型不匹配,要是不添加的话,这个m可能就变成负数了
    long double m = 231312.1312312lf // 对,数值末尾要添加标记,说明数值整数类型
    
  2. 输入输出算法

    简单输入输出格式:

    #include<iostream>
    using namespace std;
    
    int main(){
        int a ,b;
        cin >> a >>b;
        cout << a+b<<endl;
        return 0;
    }
    

    segmentation fault(数组越界)

    一次有多个输出

    #include<iostream>
    using namespace std;
    
    int main(){
        int a,b;
        cin>>a>>b;
        cout<<a+b<<' '<<a*b<<endl;
        return 0;
    }//输出比较自由,有多种输出格式,但是输出格式是一样
    #include<iostream>
    using namespace std;
    
    int main(){
        int a,b;
        cin >> a;//输入
        cin >> b;
        
        cout<<a+b;//输出
        cout<<' ';
        cout<<a*b;
        cout<<endl;
        return 0;
    }
    
    
  3. 利用scanf和printf进行输入输出

    #include<cstdio>
    #include<iostream>
    
    using namespace std;
    
    int main(){
        int a,b;
        scanf("%d %d",&a,&b);  //float对应的输入格式%f
        printf("%d %d\n",a+b,a*b);//float对应的输出格式%f
        return 0;
    }
    ————————————————————————————————————————————————
    #include<cstdio>
    #include<iostream>
    
    using namespace std;
    
    int main(){
        float a,b;
        scanf("%f %f",&a,&b);  
        printf("%f %f\n",a+b,a*b);
        return 0;
    }
    

    利用printf和scanf需要判断输入输出类型,但是利用cin、cout不用判断输出输入类型。

发现当输入输出都是float的时候,确实精确度(有效位数)是7位

当我们想保留两位小数的时候,需要对输出进行修改

printf("%.2f %.2f\n",a+b,a*b);

char类型

int main(){
    char a,c;
    scanf("%c %c",&a,&c);   //char类型对应的printf输出格式是 %c,注意%c是可能读入空格,键盘输入q w,输出q w
    						//键盘键入q  ,输出就是q  |。
    printf("%c %c",a,c);
}

%c读入空格,输出就是空格

cin>>输入 和 标准输入输出scanf 相比,cin能够过滤掉空格,scanf不能过滤空格,cin效率比较低,但是scanf效率却高

double类型

int main(){
    double a,b;
    scanf("%lf%lf",&a,&b);
    printf("%lf %lf",a,b);//对于double类型,标准输入输出格式是 %lf
}

对scanf的标准输入结束标记应该是return键,像上图输入第一个数据后,按下return键或者按下空格(对照scanf输入字符串,此时的空格起的作用是分隔两部分输入),再接着输入第二个数

long long类型:

	int main(){
    long long a,b;
    scanf("%lld%lld",&a,&b);
    printf("%lld%lld",a,b);
    return 0;
    /*
    float %f
    int %d
    double %lf
    char %c
    long long %lld
    */
}//输入输出是%lld
  1. 加减乘除以及取模运算

    #include<iostream>
    
    using namespace std;
    
    int main(){
        
        cout<< 5  % 2 <<endl;  //	取模得到1
        cout<< -5 % 2 <<endl;  // 	取模得到-1
        return 0;				//	取模结果完全取决于第一个数的正负,后面的数无所谓
    }
    
  2. 不同的变量类型之间可以相互转化

    从低精度到高精度没有任何问题,从高精度到低精度会损失一些信息,仅此而已。

    #include<iostream>
    using namespace std;
    
    int main(){
        int a = 5;
        float b = a;
        printf("%f",b);
        return 0;
    }   //得到的结果就是5.000000   float类型
    _____________________
    #include<iostream>
    using namespace std;
    
    int main(){
        
        float a = 3.14;
        int b = a;
        printf("%d",b);
        return 0;
    }	//得到的结果是3
    

    int(看成低精度) 转float,会白白提高精度;

    float转成int,会向下取整

    int和char类型之间的转化

    #include<iostream>
    using namespace std;
    
    int main(){
        
        int var = 97;
        char temp = var;
        printf("%c",temp);
        return 0;
    }
    ____________
        
    int main(){
        char var = 'a';
        int tmp = (int)var;
        printf("%d",tmp);
    }
    cout << 'A'+2 << endl;//的结果会是67,char+int会变成int类型
    cout << 3.14+2 << endl; // 的结果会是5.14,float+int会变成float。其实最终变成的类型都是倾向于变得比较强 
    

    例题:

    • 输入三个数,输出第二个整数:
    #include<iostream>
    
    using namespace std;
    int main(){
        int a,b,c;
        cin>> a >> b >> c;
        cout<< b <<endl;
        return 0;
    }
    
    • 输入a,b,c,计算\((a+b)*c\)的值:
    #include<iostream>
    
    using namespace std;
    
    int main(){
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        printf("%d",(a+b)*c);
        return 0;
    }
    

    其他具体题目见acwing

    注意还有一个头文件

    #include<bits/stdc++.h>
    
    • 给一个雇员名字、底薪、销售额,计算雇员工资
    #include<iostream>
    #include<cstdio>
    #include<string>//可以不用写这个库,<string>被包含再<iostream>库里
    using namespace std;
    
    int main(){
        string name;
        float sal,sales;
        
        //读入字符串,需要使用string 数据类型,
        //string 数据类型只能用cin,使用scanf读入会有额外的写法
        cin >> name;
        cin >> sal >> sales;
        
        printf("TOTAL = R$ %.2f",sal+0.15*sales);
        
        
        return 0;
    }
    

    abs函数被封装在

    • 钞票和硬币转换
    //用浮点数存在精度问题,建议转换成整数后用整数来做
    #include<iostream>
    #include<cstdio>
    
    using namespace std;
    int main(){
        //由N的范围,从输入样例发现都是保留两位小数,所以建议乘上100,发现之后还是没有爆掉
        float N;
        cin >> N;
        int New_N = N*100;
        
        s100 = New_N/10000; New_N = New_N - s100*10000;
        s50  = New_N/5000; New_N = New_N - s50*5000;
        s20  = New_N/2000;  New_N = New_N - s20*2000;
        s10  = New_N/1000;  New_N = New_N - s10*1000;
        s5   = New_N/500;   New_N = New_N - s5*500;
        s2   = New_N/200;   New_N = New_N - s2*200;
        
        s1   = New_N/100;   New_N = New_N - s1*100;
        s_50 = New_N/50; New_N = New_NN - s_50*50;
        s_25 = New_N/25;New_N = New_N - s_25*25;
        s_10 = New_N/10;New_N = New_N - s_10*10;
        s_05 = New_N/5;New_N = New_N - s_05*5;
        s_01 = New_N/1;
        
        cout<<"NOTAS:"<<endl;
        printf("%d nota(s) de R$ 100.00\n",s100);
        printf("%d nota(s) de R$ 50.00\n",s50);
        printf("%d nota(s) de R$ 20.00\n",s20);
        printf("%d nota(s) de R$ 10.00\n",s10);
        printf("%d nota(s) de R$ 5.00\n",s5);
        printf("%d nota(s) de R$ 2.00\n",s2);
        cout<<"MOEDAS:"<<endl;
        printf("%d moeda(s) de R$ 1.00\n",s1);
        printf("%d moeda(s) de R$ 0.50\n",s_50);
        printf("%d moeda(s) de R$ 0.25\n",s_25);
        printf("%d moeda(s) de R$ 0.10\n",s_10);
        printf("%d moeda(s) de R$ 0.05\n",s_05);
        printf("%d moeda(s) de R$ 0.01\n",s_01);
        
        
        return 0;
    }
    
  3. printf语句(在里面)

    #include<iostream>
    
    using namespace std;
    
    int main(){
        double a =3.1415926;
        
        printf("%.lf",a);   //保留三位小数   
        return 0;
    }
    

    格式化输出

    #include<iostream>
    using namespace std;
    
    int main(){
        int a=1,b=23,c=456;
        double f = 12.321
        
        //固定宽度输出
        
        printf("%5d",a);     //%d添加5表示,保留5个字符的位置,空位让空格填充,先输出1,然后从右向左填充空格
        printf("%5d",b);	 //或者可以这样说,//先输出空格//再输出1//,一共输出5个字符位置
        printf("%5d",c);
        
        
        //浮点数也有类似的输出格式
        printf("%5.1lf",f);  //这里应该表示的是:浮点数固定宽度宽是5位(默认用空格填充),保留1位小数,这里的5位是包含小数点的一位,所以输出应该是: 12.3,刚好5位
        printf("%05.1lf",f); //这里表示固定宽度是5,输出应该是:012.3,第一位不用空格填充,而是用特定字符0
        printf("%-5.1lf!",f);//表示5位字宽,保留一位小数。但是先数字,后补空格(经过试验,发现右边不能补0,只能补空格)
        return 0;
    }
    

     printf("%-5d",a); 
     printf("%-5d",b); //同样的可以这样理解-5d,是先输出数字,再输出空格,一共输出5个字符的位置,前面补空格
     printf("%-5d",c); //输出格式如下
    

	//除了补充空格,还可以补充字符,比如补充0  
    printf("%05d",a);
    printf("%05d",b);
    printf("%05d",c);  	//输出格式如下所示

printf("%5.1lf",f);  //这里应该表示的是:浮点数固定宽度宽是5位(默认用空格填充),保留1位小数,这里的5位是包含小数点的一位,所以输出应该是: 12.3,刚好5位

%8.3lf 表示一共8位有效数字数,保留3位小数,在前面补空格;

%08.3lf 表示一共8位有效数字,保留3位小数,在前面补充0;

%-8.3lf 表示一共8位有效数字,保留3位小数,在后面补充空格

实现输入两个数,输出其中较大一个,不要使用库函数

#include<iostream>
#include<cstdio>

using namespace std;
int main(){
    int a,b;
    cin>>a >> b;
    if(a > b) printf("%d",a);
    else printf("%d",b);
    
    return 0;
}

输入三个数,利用判断结构,输出其中较大的一个数

#include<iostream>
#include<cstdio>

using namespace std;

int main(){
    
    int a,b,c;
    cin >> a >> b >> c;
    
    if(a > b){
    	if(a > c){
            cout<<a<<"最大"<<endl;
        }else{
            cout<<c<<"最大"<<endl;
        }    
    }
    else{//这里省略的是a<b
        if(b > c){
            cout<<b<<"最大"<<endl;
        }else{
            cout<<c<<"最大"<<endl;
        }
    }
    
    return 0;
}

输入一个0-100的分数,如果大于等于85,输出A;如果大于等于70,并且小于85,输出B;如果大于等于60,并且小于70,输出C;如果小于60,输出D

#include<iostream>
#include<cstdio>

using namespace std;

int main(){
    
    int score;
    cin >> score;
    
    if(score >= 85){
        cout<<"A"<<endl;
    }else{
        if(score >= 70){
          	cout<<"B"<<endl;
        }else{
            if(score >= 60){
                cout<<"C"<<endl;
            }else{
                cout<<"D"<<endl;
            }
        }
    }
    
    return 0;
}

简易计算器,输入两个数以及一个算子符号,输出正确结果

注意:需要判断除数为0,以及不是+-*\的符号

#include<csdtio>
#include<iostream>

using namespace std;

int main(){
    
    //cin可以帮助我们省略空格、回车,scanf不能忽略空格和回车
    int x1,x2;
    char opa;
    cin >> x1 >> x2 >> opa;
    
    if(opa == '+'){
        cout<<x1 + x2 <<endl;
    }else{
        if(opa == '-'){
            cout << x1 - x2 <<endl;
        }else{
            if(opa == '*'){
                cout << x1*x2<<endl;
            }else{
                if(opa == '/'){
                   if(x2 == 0){
                       cout << "Divided by zero!"<<endl;
                   }
                   }else{
                       cout << "Invalid operator!"<<endl;
                   }
            }
        }
    }
    return 0;
}

判断闰年

#include<iostream>

using namespace std;

int main(){
    
    int year;
    cin >> year;
    
    if(year % 100 ==0){
        if(year % 400 == 0){
            cout<<"yes"<<endl;
        }else{
            cout<<"no"<<endl;
        }
    }else{
        if(year % 4 == 0){
            cout<<"yes"<<endl;
        }else{
            cout<<"No"<<endl;
        }
    }
    
    return 0;
}

三元素交换的swap函数手写

// 	a b c按照升序排列
int temp;
if(a > b){
    temp = b;
    b = a;
    a = temp;			//两两交换
}
if(a > c){
    temp = a;
    a = c;
    c = temp;
}
if(b > c){
    temp = b;
    b = c;
    c = temp;
}
posted @ 2021-01-31 17:21  _Sandman  阅读(212)  评论(0编辑  收藏  举报