Blue Bridge Cup C/C++ Practical Knowledge Summary

Blue Bridge Cup C/C++

head File

Universal header file:#include<bits/stdc++.h>

Although the header file reduces the burden of memorizing the header file, the compiler must actually read and analyze each included header file every time the translation unit is compiled, and the use of such header files can be reduced if unnecessary.

Utility Functions and Operators

exponentiation

pow(x,y): Indicates the power of y with x as the base. Note that the data types of x and y here should be double.

shift operator

<<: x<<y==x*(2^y)

>>:x>>y==x/(2^y)

STL sort sort() function

  • void sort(first,last);
  • void sort(first,last,comp);

The complexity is O(nlogn), and the sorting range is [first, last), including first but not last .

For example, to sort the second to ninth elements of array a from large to small, that issort(a+1,a+9,greater);

comp indicates the sorting method, and comes with 4 sorting methods: less, greater, less_equal, greater_equal. The default is to sort from small to large, that is, less.

You can also customize the sorting method, which is often used for structure sorting:

struct Student{
    char name[256];
    int score;//分数
}
bool cmp(struct Student* a,struct Student* b){
    //按分数从小到大排序
    return a->score>b->score;
}
...
vector<struct Student* >list;//定义list,把学生信息存到list里
...
sort(list.begin(),list.end(),cmp);

Advantages: It can be sorted on the original array without requiring new space; it can be sorted on the local interval of the array.

Read data sequentially

This writing method is used to continuously read a set of data until the end, and is used when the number of data to be read is not known in advance.

Note: DevC++ cannot use this writing method, but the test oj can pass.

int a[N];
int cnt=0;
while(scanf("%d",&a[cnt])!=EOF) cnt++;

STL full permutation function next_permutation()

This function is used to find the next permutation. For example, for a sequence consisting of three characters {a, b, c}, next_permutation()six permutations can be returned in lexicographical order: abc, acb, bac, bca, cab, cba. There are two forms:

  • bool next_permutation(first,last);
  • bool next_permutation(first,last,comp);

The function arranges the range [first, last), including first, excluding last .

Return value: If there is no next permutation combination, return false, otherwise return true, each time the new permutation is executed, the new permutation will be returned to the original space (for example, the original string s will become a new character permutation order).

This function is used to output larger full permutations one by one, rather than all permutations. If you want to get all the full permutations, you need to start with the smallest full permutation. If the initial full permutation is not the smallest, you need to use sort() to sort the full permutation first, and then use next_permutation() after getting the smallest full permutation , for example:

string s="bca";
sort(s.begin(),s.end());//字符串内部排序,得到最小的排列"abc"
do{
    cout<<s<<" ";
}while(next_permutation(s.begin(),s.end()));
//s.end()指向最后一个字符的下一个位置

There is also a full permutation function in C++ prev_permutation(), which is used to find the previous permutation.

Find the maximum/minimum value of an array

max_element(first,last);

min_element(first,last);

Returns the maximum and minimum values ​​in the container. Note that the interval is closed on the left and open on the right, excluding last, which is available when the scale of the topic is not large.

Initialization function memset()

The function of memset() is to set all the memory in a certain block to the specified value.

For example:memset(arr,0,sizeof(arr))

Among them, arr indicates the memory block to be filled (one-dimensional array, etc.), 0 indicates that all values ​​of the memory block are initialized to 0, and sizeof(arr) indicates the number of filled characters.

GCD (greatest common divisor) and LCM (least common multiple)

  1. GCD (Greatest Common Divisor), that is, the largest integer that can divide a and b at the same time, is recorded as gcd(a,b).

    nature:

  • gcd(a,b)=gcd(a,a+b)=gcd(a,ka+b)

  • gcd(ka,kb)=kgcd(a,b)

  • If gcd(a,b)=d, then gcd(a/d,b/d)=1, that is, a/d and b/d are mutually prime. (important)

    C++ library function (__gcd): May return negative numbers.

cout<<__gcd(15,81)<<endl;//输出3
cout<<__gcd(0,44)<<endl;//输出44,0和其他数取其他数
cout<<__gcd(0,0)<<endl;//输出0
cout<<__gcd(-6,-15)<<endl;//输出-3
cout<<__gcd(-17,289)<<endl;//输出-17
cout<<__gcd(17,-289)<<endl;//输出17

Write the GCD code by yourself, the function is exactly the same as the library function, and it may output negative numbers, and you can change int to long long when necessary .

int gcd(int a,int b){
    return b?gcd(b,a%b):a;
}
  1. LCM: the least common multiple of a and b lcm(a,b)=a/gcd(a,b)×b.

    int lcm(int a,int b){  //需要的时候把int改成long long
        return a/gcd(a,b)*b; //先做除法再做乘法,防止溢出
    }
    

C++ string functions

  • find()Function: Find

  • substr()Function: check substring

  • replace()function: replace

    string& replace(size_t pos, size_t n, const char *s);
    //将当前字符串从pos索引开始的n个字符,替换成字符串s
    
    string& replace(size_t pos, size_t n, size_t n1, char c);
    //将当前字符串从pos索引开始的n个字符,替换成n1个字符c
    
    string& replace(iterator i1, iterator i2, const char* s);
    //将当前字符串[i1,i2)区间中的字符串替换为字符串s
    
  • insert()function: insert

    Or push_back() function: insert characters at the end of the string

  • append()Function: add string

    str.append("***");Append the string after the string str

  • swap()Function: swap strings

  • compare()Function: Compare Stringss1.compare(s2)

    You can also directly compare:if(s1==s2)return true;

  • tolower()And toupper()function: convert string to case

    #include <iostream>
    #include <string>
    using namespace std;
    
    int main()
    {
        string s = "ABCDEFG";
    
        for( int i = 0; i < s.size(); i++ )
        {
            s[i] = tolower(s[i]);
        }
    
        cout<<s<<endl;
        return 0;
    }
    

Useful Data Structure Templates

vector

Vector means vector, which is a dynamic array of STL, and the size of the array can be changed as needed during operation.

The header file of vector is#include<vector>

Creation vector<int>a, vector is basically the same as array.

The push_back() function is used when adding elements, namelya.push_back(1);

The size of the array is represented by size(), that is a.size(), the size will automatically increase as the number of elements increases.

linked list list

STL list is a doubly linked list, accessing node data through pointers, its memory space can be discontinuous, using it can delete and insert nodes efficiently.

//定义一个list
list<int>node;
//为链表赋值,例如定义一个包含n个结点的链表
for(int i=1;i<=n;i++)
    node.push_back(i);
//遍历链表,用it遍历链表,例如从头遍历到尾
list<int>::iterator it =node.begin();
while(node.size()>1){
    //list的大小由STL管理
    it++;
    if(it==node.end())//循环链表,end()是list末端下一位置
        it=node.begin();
}
//删除一个结点
list<int>::iterator next=++it;
if(next==node.end())next=node.begin();//循环链表
node.erase(--it); //删除这个结点,使得node.size()自动减1
it=next; //更新it

queue

Using C++'s STL queue, you don't need to manage the queue yourself, and the code is very concise.

  • queue<Type> q: Define the queue, Type is the data type, such as int, float, char, etc.

  • q.push(item): Put the item into the queue.

  • q.front(): Return the first element of the queue without deleting it.

  • q.pop(): Delete the first element of the queue.

  • q.back(): Returns the element at the end of the queue.

  • q.size(): Returns the number of elements.

  • q.empty(): Check if the queue is empty.

C++ priority queue

The characteristic of the priority queue is that the optimal data is always at the head of the queue. The priority queue is very efficient: new data is inserted into the queue to generate a new leader element, the complexity is O(logn), and the optimal leader element is popped up to calculate the new optimal leader element in the queue, the complexity is O(logn).

The C++ STL priority queue priority_queue is implemented with a heap.

definition:priority_queue<Type,Container,Functional>

Type is the data type, Container is the container type (a container implemented with an array, the default vector), and Functional is the comparison method. These 3 parameters need to be passed in only when using a custom data type, and only need to pass in the data type when using a basic data type. If priority_queue<int>pq; the default is the big top heap, the top of the heap is the maximum value. Some operations are as follows:

  • priority_queue<Type,Container,Functional> pq: define the queue
  • pq.push(): Enqueue
  • pq.pop(): Dequeue
  • pq.size(): Returns the number of elements in the current queue
  • pq.top(): return the first element of the queue
  • pq.empty(): Determine whether it is empty (empty return 1, non-empty return 0)

stack

The characteristic of the stack is first in last out. In the commonly used recursion, the system uses the stack to save the "scene".

The related operations of STL stack are as follows.

  • stack<Type> s: Define the stack, Type is the data type, such as int, float, char, etc.

  • s.push(item): Put the item on the top of the stack.

  • s.top(): Return the top element of the stack without deleting it.

  • s.pop(): Delete the top element of the stack, but will not return. Popping out of the stack requires a two-step operation: first get the top element of the stack, and then delete the top element of the stack .

  • s.size(): Returns the number of elements in the stack.

  • s.empty(): Check if the stack is empty, return true if it is empty, otherwise return false.

set

set is a collection, which is used to check and deduplicate a set of elements (there will be no duplicate elements in the collection)

  • insert():insert
  • size(): number of elements
  • erase(): delete an element
  • clear(): Empty collection elements
  • empty(): Determine whether the collection is empty
  • find(): Find the specified element
  • upper_bound(起始地址,结束地址,要查找数值): Binary search, returns the first position greater than the value to be searched.

Binary tree storage

A node of a binary tree needs to store the value of the node and pointers to the left and right child nodes.

In the algorithm competition, in order to make the code concise and efficient, a binary tree is generally implemented with a static array. Define a static structure array of size N to store a binary tree:

struct Node{   //静态二叉树
    char value;
    int lson,rson;  //指向左右子节点的存储位置,编程时可简写为ls或l
}tree[N];     //编程时可简写为t

The space of the full binary tree tree[N] needs to be set to N=4m, which is 4 times the number of elements.

Practical Algorithm Template

sorted lexicographically

In some cases, sorting is lexicographical sorting, that is, numbers are sorted as strings. For example, sorting "7,13" is sorted lexicographically, and "713" should be output instead of "137".

bool cmp(string a,string b){  //从大到小,按字典序的反序排列
    return a+b>b+a;  //组合字符串
}

prime number judgment

When n≤10^14, judge by trial division. Complexity O(n½)

Use all the numbers in [2,n½] to try to divide n, if they are not evenly divisible, n is a prime number. Because if n has a factor smaller than n½, there is no need to try again.

bool is_prime(long long n){
    if(n<=1) return false;  //1不是素数
    for(long long i=2;i<=sqrt(n);i++)
        if(n%i==0)return false;//能整除,不是素数
    return true;
}

fast power

Using the multiplication principle.

int fastPow(int a,int n){//计算aⁿ
   int ans=1; //用ans返回结果
   while(n){  //把n看成二进制数,逐个处理它最后一位
       if(n&1) ans*=a;  //&按位与操作,如果n的最后一位是1,表示这个地方需要参与计算
       a*=a; //递推:2次方--4次方--八次方···
       n>>=1; //n右移一位,把刚处理过的n的最后一位去掉
   }
    return ans;
}

The result of exponentiation is often very large, and the general topic will ask to take the modulo first and then output. According to the nature of modulus: aⁿ mod m=(a mod m)ⁿ mod m.

Add a modulo operation to a fast exponentiation function:

typedef long long ll;
ll fastPow(ll a, ll n,ll mod){
    ll ans=1;
    a%=mod;       //重要,防止下面的ans*a越界
    while(n){
        if(n & 1) ans=(ans*a)%mod; //取模
        a=a*a%mod;    //取模
        n>>=1;
    }
    return ans;
}

Matrix multiplication and fast exponentiation

Multiplying two matrices A and B requires that the number of columns of A is equal to the number of rows of B. Let A be an m×n matrix and B be an n×u matrix, then the product C=AB is an m×u matrix, triple Loop, the complexity is O(mnu).

The power of the matrix can be calculated by fast power, which greatly improves the efficiency, and the complexity is O(N³logn), where N³ corresponds to matrix multiplication, and logn corresponds to fast power. When writing a question, a small N (number of rows and columns of the square matrix) and a larger n (power) are generally given to examine the use of fast powers.

struct matrix{int m[N][N];}; //定义矩阵,常数N是矩阵的行数和列数
matrix operator * (const matrix& a,const matrix& b){
    //重载*为矩阵乘法,注意const
    matrix c;
    memset(c.m,0,sizeof(c.m)); //清零
    for(int i=0;i<N;i++)
        for(int j=0;j<N;j++)
            for(int k=0;k<N;k++)
                c.m[i][j]+=a.m[i][k]*b.m[k][j]; //不取模
                //c.m[i][j]=(c.m[i][j]+a.m[i][k]*b.m[k][j])%mod; //取模
    return c;
}
matrix pow_matrix(matrix a,int n){//矩阵快速幂,和普通快速幂几乎一样
    matrix ans;
    memset(ans.m,0,sizeof(ans.m));
    for(int i=0;i<N;i++)ans.m[i][i]=1;//初始化为单位矩阵,类似普通快速幂的ans=1
    while(n){
        if(n&1)ans=ans*a; //不能简写为ans*=a,因为*重载了
        a=a*a;
        n>>=1;
    }
    return ans;
}

Ruler method

Also known as double pointer, it refers to using two pointers to traverse the interval at the same time during interval operation, so as to achieve high-efficiency operation. To put it simply, it is to convert the double cycle into one cycle. The complexity goes from O(n²) to O(n). like:

for(int i=0;i<n;i++)  //i从头扫描到尾
    for(int j=n-1;j>=0;j--)  //j从尾扫描到头
    {...}

//尺取法
for(int i=0,j=n-1;i<j;i++,j--)
{...}

Application restriction: require i<j

dichotomy

The concept of dichotomy is very simple, each time the search range is reduced to 1/2 of the previous one, until the answer is found.

integer dichotomy

Integer dichotomy is easy to understand and difficult to program. Due to the rounding problem of integers, it is easy to make mistakes. Application scenario: There is an ordered sequence; the problem can be modeled as finding an appropriate value on the ordered sequence.

The following example is to find the maximum value that meets the conditions in an interval 1-N.

int L=1,R=N;
//第一种写法
while(L<R){
  int mid=(L+R+1)/2;  //除以2,向右取整
  if(check(mid)) L=mid;  //新的搜索区间是右半部分,R不变,调整L=mid
  else   R=mid-1;   //新的搜索区间是左半部分,L不变,调整R=mid-1
}
cout<<L;
//第二种写法
while(L<R){
  int mid=(L+R)/2;  //除以2,向左取整
  if(check(mid)) L=mid+1;  //新的搜索区间是右半部分,R不变,更新L=mid+1
  else   R=mid;   //新的搜索区间是左半部分,L不变,更新R=mid
}
cout<<L-1;

real dichotomy

Real number dichotomy does not need to consider the problem of integer rounding, which is easier. can be used to find the roots of the equation.

const double eps=1e-7;   //精度,如果用for循环,可以不要eps
while(right-left>eps){   //for(int i=0;i<100;i++)
    double mid=left+(right-left)/2;
    if(check(mid))right=mid;  //判定,然后继续二分
    else left=mid;
}

prefix and

An array a[0]~a[n-1] of length n, its prefix sum sum[i] is equal to the sum of a[0] to a[i].

Using recursion, all prefix sums can be calculated only n times: sum[i]=sum[i-1]+a[i].

You can also use sum[] to calculate a[]: a[i]=sum[i]-sum[i-1]

Quickly calculate the value of any interval a[i]~a[j] in the array: sum[j]-sum[i-1]

application:insert image description here

//例:当n=4时,ans=a1*a2+a1*a3+a1*a4+a2*a3+a2*a4+a3*a4 =a1*(a2+a3+a4)+a2*(a3+a4)+a3*a4
#include <iostream>
using namespace std;
int main()
{
  unsigned long long S=0;
  int n;
  cin>>n;
  int *a=new int[n];
  for(int i=0;i<n;i++)cin>>a[]
  unsigned long long *sum=new unsigned long long[n-1];//利用前缀和求解
  sum[0]=a[0]; 
   for(int i=1;i<n-1;i++){
    sum[i]=sum[i-1]+a[i];
  }
  for(int i=1;i<n;i++){
      S+=sum[i-1]*a[i]; 
  }
  cout<<S;
  return 0;
}

Search (DFS and BFS)

For details, please refer to: DFS and BFS

Application scenario:

  • DFS: Find all paths (permutation and combination, regular problem, output maze all paths)
  • BFS: find the shortest path

computer tool

Excel use

to sum

Example questions are as follows:

insert image description here

Fill in the denominator in column B of the Excel table, each row is twice the size of the previous row, fill in "=B1*2" in cell B2, and then move the mouse pointer to the lower right corner of cell B2, when the pointer becomes a cross shape , hold down the left mouse button and drag down to the 20th line, the denominator is filled in.

insert image description here

The final pass sums. The denominator is 524288 in cell B20, and the calculation formula of the numerator is actually "SUM(B1:B20)". As long as the range B1 to B20 is selected, Excel will automatically calculate the result 1048575.

insert image description here

date issue

There are many problems in the algorithm problem that involve finding the difference in days between two dates. The specific method is as follows:

Select the cell and select "DATE" in the formula - date and time, and fill in the date.

insert image description here

Use the formula to calculate the result.

insert image description here

Windows built-in calculator

During the exam, you can use the calculator that comes with Windows to solve some math problems.

For example, asking for 1000! , open the calculator, select the "scientific" mode, input the number 1000 that requires factorial, and then click n! to get the result.

insert image description here

Guess you like

Origin blog.csdn.net/m0_61443432/article/details/129968845