• 笔记



    title: 笔记
    date: 2020-08-20
    categories: acm
    tags: acm
    top: true

    就是做题遇到的问题,解决的思路;还有细节...

    一般认为计算机每秒 1e8条(做题还是当成1E7吧)简单语句,估计一下复杂度和量级可以估算自己的时间,一般百万级(不超过1000万比较好)。一般内存32/64MB。

    参考资料:紫书等等见https://github.com/TouwaErioH/ACM/tree/master/%E6%95%99%E6%9D%90

    1 常见算法/数据结构

    https://www.cnblogs.com/lqerio/p/13535931.html

    2 STL

    2.1 map

    using namespace std;
    typedef pair<int,int> info;
    
    map<string,info> family = {{"Adam",make_pair(1,930)},{"Seth",make_pair(2,912)}}; /初始化 
    
    info p;
    map<string,info> person;
    p=make_pair(1,930); //p.first,p.second
    person.insert(make_pair("Adam",p));  //插入 注意 make_pair
    
    map<string,info>::iterator iter1; //迭代器
    
    if(family.count(name1)>0)  //map在find前要先count确定存在
    iter1=family.find(name1);  //find 返回迭代器
    
    iter1->second.first==-1;  //注意map的迭代器用-> 。  pair用.   
    
    iter->first iter->second;
    

    2.2 pair

    typedef pair<int,int> info;   //这样做类型。
    
    info p;
    p=make_pair(1,930);  //赋值
    
    p.first,p.second  //使用
    

    2.3 queue

    void clearque(queue<Node>& q){  //注意 &
        queue<Node> empty;
        swap(empty, q);
    }
    
    

    2.4 vector

    注意map,vector,queue每次使用要清空(vec.clear,while(!empty)queue.pop)

    不同于map(map有find方法),vector本身是没有find这一方法,其find是依靠algorithm来实现的。
     vector<int>::iterator it = find(vec.begin(), vec.end(), 6);
     
        if (it != vec.end())
            cout<<*it<<endl;
        else
            cout<<"can not find"<<endl;
    
    count 类似
    

    2.5 string

    string.length() .size()
    
    bool cmp1(string a,string b){
        return a<b;
    }
    vector<string>ans;
    sort(ans.begin(),ans.end(),cmp1);
    

    3 技巧

    3.1 浮点数精度

    设置eps=1e-9。fabs(a-b)<eps 则认为a==b。

    fabs ,abs 在 cmath

    3.2 结构体构造函数

    struct node
    {
        int key;
        int height;
        int size; //tree node 个数
        node *left, *right;
        /*
        node(int x) : key(x), height(1), size(1), left(NULL), right(NULL) {}
            node() : key(NULL), height(NULL), size(NULL), left(NULL), right(NULL){}
            */
           node(int k)
        {
            key = k;
            height = 1;
            size = 1;
            left = right = 0;
        }
    };
    
    
    struct node{
        int data;
        string str;
        char x;
        //自己写的初始化函数
        void init(int a, string b, char c){
            this->data = a;
            this->str = b;
            this->x = c;
        }
        node() :x(), str(), data(){}
        node(int a, string b, char c) :x(c), str(b), data(a){}
    }N[10];
    
          N[1] = { 2,"c++",'d' };    //无参默认结构体构造体函数
          N[2].init(3, "java", 'e'); //自定义初始化函数的调用
          N[3] = node(4, "python", 'f'); //有参数结构体构造函数
    

    3.3 new && 不定长数组

    char* Data = new char[N]; // 不定长数组
    
     int *a = new int[5];
    
          delete []a;    //释放int数组空间
    
    
    
    

    3.4模运算

    被除数÷除数=商……余数。
    由此可知,余数=被除数-商×除数 (*)

    以下摘录自C++ Primer(P130)

    操作符%称为“求余”或“求模”操作符,该操作符的操作数只能为整型。

    如果两个操作数为正,结果也为正;如果两个操作数都为负数,结果也为负数;如果一个操作数为正数,一个操作数为负数,求模结果的符号取决于机器。

    当操作数中有一个为负,一个为正是,求模操作结果值的符号可依据分子(被除数)或分母(除数)的符号而定。
    如果求模的结果随分子的符号,则除出来的值向零一侧取整;如果求模与分母的符号匹配,则除出来的值向负无穷大一侧取整。

    取模运算https://baike.baidu.com/item/%E5%8F%96%E6%A8%A1%E8%BF%90%E7%AE%97/10739384?fr=aladdin

    3.5 奇偶判断

    len&1==1  奇数  (这里不能用亦或,想想就知道因为 &1 相当于& 000001)
    

    3.6 数组开法

    woj1019 ,因为输出 是按行,所以记录数组应该是[classnum][day]的形式

    operator<

    见c++ categories 下有一篇分析

    struct problem{
        int time,penalty;
        bool operator <(const problem &tmp)const{
            return penalty>tmp.penalty;
        }
    };
    
    /* 多个大小比较时
     if(a.grade != b.grade) 
            return a.grade < b.grade; 
        else if(t != 0)
            return t < 0; 
        else
            return a.age < b.age;
    */
    

    4 常见错误

    4.1 除0

    比如a/b6,最好用a-6*b0

    4.2 segment fault

    https://blog.csdn.net/qq_36589706/article/details/81505221

    char *c = "hello world";
        c[1] = 'H';
    char c[]="helloworld";  //前者c是地址,指向常量"hello world",不可修改
    
    
    int  i=0;
    scanf ("%d", i);  /* should have used &i */
    printf ("%d
    ", i);
    return 0;
    
    int *p = null;
    *p = 1;
    
    数组越界
    
    printf("%s
    ", b);
      return 0;   //整数当成地址,一直遇到0才停。
      
    栈溢出
    	
    

    4.3 引用传递

    引用导致修改,或者忘了引用没有修改。

    4.4 数组大小开的不对

    太大了溢出,太小了容易越界 (这主要是细节,比如woj 1006 200 0000 我写成 20000+5就segmenetfault了,这种错误我犯过很多次)

    4.5 运算符优先级

    // 主要是记得加括号,比如
    tmp=(tmp>maxtri[j][i])?maxtri[j][i]:tmp;   //注意加括号
    
    

    4.6 double int

    // 涉及浮点数注意 比较+eps (精度要求很高的时候)
    (capacity[j][i]>maxcap&&cnt[j]>0){   //常见错误,直接==0(double a>b) 应该用eps。但是这里数据在100,精度没那么高直接用也行
    
    //int double 注意*1.0
    
    avg=((double)minh+maxh)/2;         //注意double
    

    4.7 语句位置

    //常见错误 放错位置,注意语句在哪个结构({括号)
    
    //;maxcap=capacity[j][i];  //常见错误 ij反了,注意意义!!。比如建图时先人再动物,然后遍历的时候先动物,ij就要反过来 见woj 1008
    

    4.8 全局变量

    不小心修改了全局变量导致出错
    如woj1009,全局变量m为边数,但是spfa模板中addedge()里也有一个m,就改了。解决是修改addedge()中的m为edgenum
    
    const int x=5; 不要 int x;
    

    4.9 整数溢出

    4.9.1 最后取模转到过程中

    主要是连续+,*的溢出。一般题目告诉你最后取模,边计算边取模就好了

    for(i=0;i<num-1;i++){
                maxn=maxn*2;
                maxn=maxn%2006;  //防溢出
            }
    

    4.9.2 负数取模

    模运算见 3.4
    负数取模应该保证是正数才不会错

    x=)=(x%mod+mod)%mod
    

    4.10 数据类型选择

    选择合适的double,int,longLong...同时输出注意对应,比如%lld

    woj1012
    ans用long long
    

    4.11 C++ 标准库y1 变量声明为y1的问题

    显示变量y1 和C++标准库中的某个变量名称冲突,这个问题应当引起注意。
    另外这不是头文件写成<bits/stdc++.h>引起的,即使换成各具体的头文件(<iostream>, <algorithm>, <ctring>)还是会返回这个错误。
    具体原因及解决办法还有待研究。
    
    main.cpp:4:17:错误:'double y1'被重新声明为另一种符号
    double x1,x2,x3,y1,y2,y3,z1,z2,z3; 
                     ^〜
    在从/usr/include/features.h:424:0包含的文件,
                     从/usr/include/x86_64-linux-gnu/c++/7/bits/os_defines.h:39,
                     从/ usr /包括/ x86_64的-linux-gnu / c ++ / 7 / bits / c ++ config.h:533,
                     来自/ usr / include / c ++ / 7 / cstdio:41,
                     来自main.cpp:2:
    / usr / include / x86_64-linux- gnu / bits / mathcalls.h:221:1:注意:先前的声明'double y1(double)' 
    __MATHCALL(y1 ,,(_Mdouble_)); 
    

    4.12 C 和C++ char数组赋值''的问题

    woj 1013
    mapp[i][len]='';  //C可以这样,C++不行。 Array must be initialized with a brace enclosed initializer
    mapp[i][len]=; c++还没找到解决办法。建议用string代替  可能是直接赋值被当成初始化了?
    

    4.13 考虑不全

    woj1019,课程名说有空格,没有说只有一个空格,要考虑多个空格

    4.14 初始化/每次循环初始化(清零)

    包括变量(数组)的初始化

    每次循环把上次结果清零

    queue,vector等的清空

    5 其他函数

    5.1 cctype

    包含 isalpha,isdigit...

    isalpha = s[0] >= 'a' && s[0] <= 'z') || (s[0] >= 'A' && s[0] <= 'Z')

    5.2 memset

    // memset(final,0,sizeof(int)*4); 注意memset是字节为单位,只能赋值0。比如int 4字节0000 0X01010101.
    //速度慢 另外注意一个字节2个16进制数
    // memset(a,0x3f,sizeof(a))
    

    5.3 sqrt pow

    <cmath>
    sqrt return double
    pow(a,b)a^b
    

    5.4 abs fabs

    cmath
    对应整形浮点型
    
    C语言中,
    求整数的绝对值abs()和labs()应该包含stdlib.h
    求浮点数的绝对值fabs()应该包含math.h
    在C++中,只需要包括cmath即可。
    

    5.5 sort qsort 推荐用sort

    algorithm
    sort 推荐,一般更快
    sort(first_pointer,first_pointer+n,cmp) //sort(mapp,mapp+5,cmp) sort(vec.begin(),vec.end())
    cmp bool返回
    
    不推荐
    cstdlib
    void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*))
    base-- 指向要排序的数组的第一个元素的指针。
    nitems-- 由 base 指向的数组中元素的个数。
    size-- 数组中每个元素的大小,以字节为单位。
    compar-- 用来比较两个元素的函数,即函数指针(回调函数).
    cmp 用int返回,需要const void*
    int compare(const void *a,const void *b)
    {
         return *(int*)b-*(int*)a;//从大到小排序,若从小到大牌组为:*(int*)a-*(int*)b
    }
    

    6.输入输出

    6.1 scanf printf

    scanf 函数是有返回值的,它的返回值可以分成三种情况

    1. 正整数,表示正确输入参数的个数。例如执行 scanf("%d %d", &a, &b);
      如果用户输入"3 4",可以正确输入,返回2(正确输入了两个变量);
      如果用户输入"3,4",可以正确输入a,无法输入b,返回1(正确输入了一个变量)。
    2. 0,表示用户的输入不匹配,无法正确输入任何值。如上例,用户如果输入",3 4",返回0。
    3. EOF,这是在stdio.h里面定义的常量(通常值为-1),表示输入流已经结束。
      在Windows下,用户按下CTRL+Z(会看到一个^Z字符)再按下回车(可能需要重复2次),就表示输入结束;
      Linux/Unix下使用CTRL+D表示输入结束。
      本题(woj1007 feedind animals)可以使用下面的代码来处理输入:
        while (scanf("%d", &n) == 1) / 或!= EOF , 但前者更好 /
    

    woj1009 输入数字和字符,同时空格间隔

    //这样写有问题。读了空格
    scanf("%d%d%d%d%d",&from,&to,&power,&speed,&dist);
    scanf("%c",&word);
    
    scanf("%d%d%d%d%d",&from,&to,&power,&speed,&dist);
    getchar();scanf("%c",&word);getchar();   //处理最后一个字符前的空格这样可以,但是麻烦
    
    //推荐
    scanf("%d %d %d %d %d %c",&from,&to,&power,&speed,&dist,&word);  //注意%c不是%s 。也可以fstream
    

    顺便说一下,printf的返回值是输出的字符数,例如,printf("1234")的返回值是4,而printf("1234 ")的返回值是5。

    6.2 输入结束 EOF

    1.while((scanf"%d,%d",&m,&n)==2)
    
    2.while((scanf"%d,%d",&m,&n)!=EOF)
    
    3.while(cin>>m>>n)
    

    6.3 空格截断 getline

    注意cin 空格截断,如果不想截断用getline。

    //比如
    string line;  getline(cin,line);
    
    istream& getline ( istream &is , string &str , char delim ); 
    
    string line;
        while(getline(cin,line,'#'))
        cout <<line;
     
     // You are the #best!  剩下的在缓冲区  EOF仍然可退出 然后#不会读入
    //fflush(stdin);清空
    

    6.4 缓冲区

    fflush(stdin)
    

    6.5 读题

    // woj1009  题目说了每个测试有空行 所以 每个例子后面 getchar() 一下
    
    

    6.6 float double int (数据类型)

    float,单精度浮点型,对应%f.
    double,双精度浮点型,对应%lf.
    在用于输出时:
    float类型可以使用%lf格式,但不会有任何好处。
    double类型如果使用了%f格式可能会导致输出错误。
    在用于输入时:
    double 类型使用了%f格式,会导致输入值错误。
    float类型使用double类型不仅会导致输入错误,还可能引起程序崩溃。
    
    2^16 =65536
    
    [-2^31,2^31),即-2147483648~2147483647约等于2e9,
    

    7 数学知识

    7.1 几何

    7.1 三角

    woj 1017
    //余弦定理  cos A=(b²+c²-a²)/2bc
    ///正弦定理  a/sinA = b/sinB =c/sinC = 2r=D(r为外接圆半径,D为直径)
    //圆周角定理 圆周角所对弧对应角为圆周角的二倍 
    //(海伦公式)(p=(a+b+c)/2)
    //S=sqrt[p(p-a)(p-b)(p-c)]
    // 三角形面积 1/2*b*c*sina
    

    7.2 行列式(线性代数)

    woj 1014
    二阶三阶行列式求值可以用沙路法(对角线法则)

    行列式就是线性变换的伸缩因子,
    //原来的体积是1,经过矩阵的线性变换的体积就是1*矩阵行列式

  • 相关阅读:
    gitblit 配置图文详解
    springmvc文件下载之文件名下划线问题终极解决方案
    redis实战进阶
    关于B+树, 你要了解的都在这里
    http的长连接和短连接(史上最通俗!)以及应用场景
    Base64的前世今生
    Springfox集成Swagger2实战篇
    Minio使用详解
    ubuntu系统五笔输入法安装
    YouTube排名第一的励志英文演讲《Dream(梦想)》
  • 原文地址:https://www.cnblogs.com/lqerio/p/13484897.html
Copyright © 2020-2023  润新知