晴问算法题库解题记录

晴问算法题库解题记录

晴神的网站 牛!!
在此处记录一下本人解题的过程,一些注意点,知识点

一、入门类别

1.各个类型

  • 整型int:%d的范围是从 − 2 31   2 31 − 1 -2^{31}~2^{31}-1 231 2311(即从-2147483648到2147483647),简单估算可以认为是绝对值在 2 ∗ 1 0 9 2*10^9 2109以内。【大致10位数字】输出几位两位整数%02d
  • 长整型long long:%lld的范围是从 − 2 63   2 63 − 1 -2^{63}~2^{63}-1 263 2631,简单估算可以认为是绝对值在 9 ∗ 1 0 1 8 9*10^18 91018以内。【大致18位数字】
  • 字符型char:%c
  1. scanf()函数:scanf可以通过指针的方式理解。这篇博文讲解的很详细,非常感谢
  2. printf()函数:可以控制输出位数。输出两位浮点数%.2f,输出浮点整数%.0f。
  3. 强制类型转换:如(double)a。
  4. 运算符
  • 整除/:这是保留整数部分。如果想要使用浮点出发,需要将其中一个数(或两个数)强制转变为浮点型才可以。
  1. 定义常量:用const。如const double PI=3.14
    有两种方法#define和const但define是宏替换,一般不在这里使用。常量变量名一般用全大写。
  2. 条件运算符:如a>b?a=2:b=1
  3. 换行符:\n。注意方向
  4. 字符串转换:to_string()。注意要引用< string >
  5. getchar函数:用来输入单个字符。如c=getchar()。有一些题目需要先输入一个整数,然后输入多行字符串,这时候如果用gets、getline之类用来输入字符串的函数,都会把换行给接收到,导致输入的结果有问题。这时候可以考虑用getchar来接收整数后的换行,使后续的整行字符串能顺利读入
  6. 数学函数
    以下都接收浮点型,返回的也是浮点型。
  • fabs(a):a的绝对值
  • floor(a):a的向下取整
  • ceil(a):a的向上取整
  • round(a):a的四舍五入(实际是四舍六入五成双)
  • pow(a, b):a的b次方,其中b也可以是浮点型
  • sqrt(a):a的算术平方根(即开根号)
  • log(a):a的以自然对数
    为底的对数
  1. 条件判断语句:
  • if语句
  • if-else
  • switch:配合case和default以及break和continue
  1. 循环语句
  • while
  • do……while
  • for
  1. 交换函数:可以直接引用algorithm的swap
  2. 全局数组:当我们试图在函数中开一个大数组时,很容易使程序报错退出,这是因为在函数(包括主函数)中定义变量时,变量会存放在“栈”区,栈区可以分配的内存较小,所以在开大数组的时候会因为申请不到内存而报错退出。而如果我们把数组开在函数外面,那么将会存放在“堆”区,堆区可以分配的内存较大,适合开大数组。
  3. memset函数:memset函数在string.h或cstring头文件下,可以将数组中每个元素以字节为单位赋值
    举例来说:
  • 由于1个int型变量占用4个字节,对每个字节都赋值0的时候,因0的二进制为全0(即00000000),因此这4个字节的二进制拼起来后每一位都是0(即00000000000000000000000000000000),对应的十进制为0,所以最终数组每个元素都是0;
  • 由于1个int型变量占用4个字节,对每个字节都赋值-1的时候,因-1的二进制为全1(即11111111),因此这4个字节的二进制拼起来后每一位都是1(即11111111111111111111111111111111),对应的十进制为-1,所以最终数组每个元素都是-1;
  • 【注意!】由于1个int型变量占用4个字节,对每个字节都赋值1的时候,因1的二进制为00000001,因此这4个字节的二进制拼起来后是00000001000000010000000100000001,对应的十进制为16843009,所以最终数组每个元素都是16843009;
  • 由于1个char型变量只占用1个字节,因此对char型数组进行memset操作时,最终数组每个元素的值就是赋的值本身。
    最常见的就是用memset函数给数组赋值0或者-1,想赋其他的值如果对二进制不熟的话建议不用memset,而用fill函数
    如:
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXV=10;
int a[MAXV];

int main(){
    int x;
    scanf("%d",&x);
    memset(a,x,sizeof(a));
    printf("%d",a[0]);
}
  1. 字符串输入输出

字符串数组定义:

const MAX_LEN = 100;
char str[MAX_LEN];

【总结】

  • C++:使用cin.getline(str, MAX_LEN)
  • 想玩花活的(非必要不建议):使用scanf(“%[^\n]”, str)或fgets(str, MAX_LEN, stdin)

第一种最好使用,也够用了~
cin.getline:仅C++可用,C语言不可用。需要添加 #include < iostream >头文件,并且在头文件后增加一行using namespace std;。然后我们可以像下面这样使用,其中第一个参数是字符数组,第二个参数是最大允许读入的字符个数,设置为字符数组的长度即可。

C++
cin.getline(str, MAX_LEN);

后两者可以看晴神的笔记~

同时cin.getline可以配合puts()输出。

  1. 字符串长度
    当我们有一个字符数组str后,只需要使用strlen函数即可获得该字符数组的长度,使用strlen函数前需要先引入string.h或cstring头文件。
    strlen函数的实现原理是,从头开始扫描字符数组,直到碰到结束符\0时结束扫描。由于这个遍历的过程,使得strlen函数的时间复杂度是O(len),其中len表示字符数组的长度。因此,当我们需要遍历字符串时,尽可能提前使用strlen函数计算好长度,而不要在for循环中写类似for (int i = 0; i < strlen(str); i++)的语句,因为这会导致每次循环都要重新执行strlen函数来计算一次长度,使整体时间复杂度上升一个级别。

  2. *string和char s和char s[ ]的区别
    string 和 char *s的区别看这篇博文比较详细,非常感谢~
    char *s和char s[ ]的区别看这篇博文,非常感谢~

  3. 字符串拼接:strcat

  4. sscanf和sprintf:可以理解为string+scanf和string+printf。

  • sscanf():从左至右的赋值。如:sscanf(str,“%d”,&n):把str以%d的形式赋给n;
  • sprintf():从右至左的赋值。如sprintf(str,“%d”,n):把n的数据以%d的形式写到str里。
    这里sscanf会返回一个返回值。函数将返回成功赋值的字段个数;返回值不包括已读取但未赋值的字段个数。返回值为0 表示没有将任何字段赋值。 如果在第一次读取之前到达字符串结尾,则返回EOF。
  1. int to string
    使用string中的to_string,如
#include<string>

string s = to_string(a);
  1. char to int
    使用ASCII码原理,如:
char a;
a = a-'0';
  1. 回文串
    只需要循环前一半即可。
#include<cstdio>
#include<iostream>
#include<string>
using namespace std;
const int MAXN=50;

bool judge(string s){
    int len=s.length();
    for(int i=0;i<len/2;i++){
        if(s[i]!=s[len-i-1]) return false;
    }
    return true;
}

int main(){
    string s;
    cin>>s;
    if(judge(s)) cout<<"YES";
    else cout<<"NO";
    return 0;
}
  1. 由于单点测试可以通过EOF结束输入
while(scanf("%s",s[num])!=EOF){
...
}
  1. 公共前缀
    注意这里getchar()
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int MAXN=51;


int main(){
    int n;
    scanf("%d",&n);
    char s[n][MAXN];
    int minL=MAXN;
    getchar();
    for(int i=0;i<n;i++){
        cin.getline(s[i],MAXN);
        int len =(int)strlen(s[i]);
        if(len<minL) minL=len;
    }
    for(int i=0;i<minL;i++){
        bool flag=true;
        string str="";
        for(int j=1;j<n;j++){
            if(s[j][i]!=s[0][i]){
                flag=false;
                break;
            }
        }
        if(flag) printf("%c",s[0][i]);
        else{
            break;
        };
    }
    printf("\n");
    return 0;
}

将继续更新

  • 26
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值