[Preparation for the 13th Blue Bridge Cup] Some personal tips and precautions when solving C/C++ problems (continuously updated)

[Preparation for the 13th Blue Bridge Cup] Some personal tips and precautions when solving C/C++ problems (continuously updated)


Let me talk about some nonsense first: I recently feel that writing algorithm questions is like playing a fighting game. Fighting is mainly divided into two processes: confirmation and continuous attack after confirmation . The confirmation test is the ability of the player to quickly cut into the problem, that is, basically determine what algorithm to use to solve the problem; and the continuous attack after the confirmation is to accurately play the combo that he practiced. This test is the proficiency of the player. For algorithm masters, their algorithm accumulation is undoubtedly very deep, and their hand speed is also very fast. Therefore, for them, whoever confirms the problem faster will have an advantage in the game. But for a rookie like the author, even if he happens to steal the "bottom" of the question, he will often make mistakes in the process of using the combo, which will lead to disconnection , and finally be KO by the question. Why is it disconnected ? To put it simply, it is because of insufficient practice, but it can be further subdivided into two parts: one is that the algorithm is not proficient, and the other is that a fast and robust coding habit has not been formed, such as always getting stuck on input and output, and always Repeatedly hand typing data, etc., of course, this is mainly due to lack of deep knowledge of the language and lack of experience.

This article does not focus on the algorithm process of specific problems, but mainly shares some points of attention and coding skills other than the algorithm that I think. Make sure that you can use "a set of combos to quickly take away" the problem under the premise of knowing the problem-solving algorithm , so as not to die tragically in all aspects other than the algorithm. This also allows us to focus more on algorithm design and avoid wasting a lot of time.

input Output

  1. Considering efficiency issues, try to use scanf()and for standard input and output printf(), and try not to mix std::cinand and scanf()and std::coutand (sometimes there will be problems, such as the following situation, to speed up std::cin and std::cout, at this time you must not use printf()The output of C and C++ is mixed, see [1] for specific examples).
	std::ios::sync_with_stdio(false);  // 取消cout和printf的兼容,此后不能将输出流混用
	std::cin.tie(0);  // 解除std::cin和std::cout的绑定
  1. Input and output of long long type: scanf("%I64d", &n);. Note that it is the letter I (i), not l (L), and it must be capitalized. Note: When doing questions in Luogu, %I64dit should be changed to %lld.

  2. Output integers with leading zeros, such as time format HH::MM::SS, print statements should be printf("%02d:%02d:%02d\n", h, m, s);, and so on for other cases.

array

  1. Sometimes it is necessary to open a relatively large array in advance, and the size is often represented by a macro, as shown in the following code. If used, #define MAXN (1e5 + 5)an exception will be thrown size of array 'A' has non-integral type 'double', because the array subscript must be an integer type.
    #define MAXN 100005
    int A[MAXN];
    
  2. Array naming should try to avoid conflicts with naming in STL, such as left, right, count, mapand so on.

data structure

1. Segment tree

Pay attention to the subscript of the original input array A. The subscript of the root node of the line segment tree template is usually 1, so the Asubscript of the starting point of the array should also start from 1 as much as possible; if it Astarts from subscript 0, a unified subscript operation is required. For example, the following piece of code realizes the point-modified line segment tree. Since the input array starts from 0, it needs to convert the subscript when building the tree and calling it. For the original title, see leetcode307. Area and retrieval.

class NumArray {
    
    
private:
    int n;
    typedef struct{
    
    
        int l, r;
        int sumv;
    }tree;
    #define MAXN 30001
    tree T[MAXN*4];
    // 建树
    void build(int o, vector<int>& A){
    
    
        int L = T[o].l, R = T[o].r;
        int lc = o*2, rc = o*2+1;
        if(L == R){
    
    
            T[o].sumv = A[L-1]; // 1:下标要减1, A[0...n-1]
            return;
        }    
        int M = L + (R - L) / 2;
        T[lc].l = L, T[lc].r = M;
        T[rc].l = M+1, T[rc].r = R;
        build(lc, A);
        build(rc, A);
        T[o].sumv = T[lc].sumv + T[rc].sumv;
    }
    void pushup(int o){
    
    
        T[o].sumv = T[o*2].sumv + T[o*2+1].sumv;
    }
    void update(int o, int x, int val){
    
    
        int L = T[o].l, R = T[o].r;
        if(L == R){
    
    
            T[o].sumv = val;
            return;
        }
        else{
    
    
            int M = L + (R - L) / 2;
            if(x <= M){
    
    
                update(o*2, x, val);
            }
            else{
    
    
                update(o*2+1, x, val);
            }
            pushup(o);
        }
    }
    int query(int o, int ql, int qr){
    
    
        int L = T[o].l, R = T[o].r;
        if(ql <= L && R <= qr){
    
    
            return T[o].sumv;
        }
        int M = L + (R - L) / 2;
        int sumv = 0;
        if(ql <= M){
    
    
            sumv += query(o*2, ql, qr);
        }
        if(qr > M){
    
    
            sumv += query(o*2+1, ql, qr);
        }
        return sumv;
    }
    
public:
    NumArray(vector<int>& nums) {
    
    
        n = nums.size();
        T[1].l = 1, T[1].r = n;
        build(1, nums);
    }
    
    void update(int index, int val) {
    
    
        update(1, index+1, val); // 2:下标index要加1
    }
    
    int sumRange(int left, int right) {
    
    
        return query(1, left+1, right+1);  // 3:0 <= left, right < n,要加1
    }
};

debugging

  1. Functions can be used freopento redirect the input and output streams and put the data in the file. The author gives a simple debugging template here . By default, a new file named is created under the current folder where the code is executed in1.txtto store the input of the use case. Pay attention to the number of use cases in the first line of the data file; you only need to #define DEBUGMODEcomment out the code when submitting the code.
    #include<iostream>
    #include<cstdio>  // freopen()在此标准库中 
    using namespace std;
    #define DEBUGMODE  // 提交代码时注释掉即可
    
    int main(){
          
          
    	int tCase = 1; // 测试用例数目 
    	#ifdef DEBUGMODE
    	freopen("in1.txt", "r", stdin);
    	scanf("%d", &tCase);
    	//freopen("out1.txt", "w", stdout); // 如果想把结果保存到文件,取消该句注释 
    	#endif	
    	while (tCase--){
          
          
    		// 在这里放置算法的代码
    		// ...
    	}
    	#ifdef DEBUGMODE
    	cin.get();  // 用stdout时,避免界面直接关闭,从而看不到输出结果
    	cin.get();  
    	#endif
    	return 0;
    }
    

If there is something wrong with the description in this article, or if there is a better solution, please communicate and correct me!

References

[1] LT-Y. side effect of sync_with_stdio(false)[EB/OL]. https://www.cnblogs.com/Little-Turtle–QJY/p/13832888.html, 2020-10-17.

Guess you like

Origin blog.csdn.net/weixin_42430021/article/details/123426388