zoukankan      html  css  js  c++  java
  • 计算机考研复试机试重点问题总结

    2020.8.21-2020.9.6 the first version

    1 闰年

    (year % 4 == 0 && year % 100 != 0) || (year % 400 = 0)
    预处理每个月的天数,用空间换时间
    int daytab[2][13]={
        {0,31,28,31,30,31,30,31,31,30,31,30,31}
        {0,31,29,31,30,31,30,31,31,30,31,30,31}
    }

    2 保留几位输出

    3.C语言读取text文件

    #include<iostream>
    #include<stdio.h>
    using namespace std;
    int main(){
    	
    	//逐行写 
    	FILE *fp = NULL;
        char buffw[26];
        
    	fp = fopen("1.txt", "w+");
    	for(int i=0;i<26;i++){
    		buffw[i]='a'+i;
    	} 
    	//fprintf(fp, "This is testing for fprintf...
    ");
    	fputs(buffw,fp);
        fclose(fp);	 
        
        //逐行读 
    	//FILE *fp=NULL;
    	char buffr[255];
    	fp = fopen("D:\devcpp\baoyan\1.txt", "r");
    	while(!feof(fp)){
    		fgets(buffr,255,fp);
    //	printf("%s
    ", buff); 
        	cout<<buffr;
    	}
    	fclose(fp);
    }
    
    
    c++读取文件首选
    #include<iostream>
    #include<fstream>
    #include<stdio.h>
    using namespace std;
    int main(){	
    	//写入 
    	fstream wfile;
    	wfile.open("1.txt");
    	char sdata[26];
    	for(int i=0;i<26;i++){
    		sdata[i]='z'-i;
    		wfile << sdata[i]<<endl;
    	}
    	//cout<<sdata<<endl;
    	wfile.close();
    	
    
    	//读取 
    	string data="";
    	fstream rfile;
    	rfile.open("1.txt");
    	//rfile.getline(data,27);//读取num-1个字符 
    	while (getline(rfile,data))
    	cout << data << endl;
    	rfile.close();
    	return 0;
    	
    } 
     

    4.vector容器

    //vector容器
    #include<iostream>
    #include<vector>
    #include<algorithm>
    using namespace std;
    int main(){
    	vector<int>obj;
    	vector<int>::iterator it;
    	for(int i=5;i>=0;i--){
    		obj.push_back(i);
    	}
    	//sort(obj.begin(),obj.end());
    	for(it=obj.begin();it!=obj.end();it++){
    		cout<<*it<<" ";
    	}
    	
    	return 0;
    }

    5 sort函数

    sort(first,last,comp)
    起始地址first,last
    comp 排序方式默认升序
    重写sort函数可以变为降序
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    using namespace std;
    bool compare(int a,int b) { 
    	return a>b; //升序排列,如果改为return a>b,则为降序 
    }
    int main(){
    	int n=5;
    	int arr[n];
    	for(int i = 0; i < n; i++){
    		scanf("%d",&arr[i]);
    	}
    	sort(arr,arr+n,compare);
    	for(int i = 0; i < n; i++){
    		printf("%d ",arr[i]);
    	}
    	return 0;
    }
    compare函数:
    比较函数,在遇到新的排序规则时,黄金法则:当比较函数返回值为true时,表示比较函数是第一个参会将排在第二个参数前面。
    #include<iostream>
    #include<algorithm>
    #include<string>
    using namespace std;
    struct student{
        string name;
        int grade;
        int order;
    };
    bool compare1(student a,student b){
        if(a.grade==b.grade){
            return a.order<b.order;
        }
        else{
            return a.grade>b.grade;
        }
    }
    bool compare2(student a,student b){
        if(a.grade==b.grade){
            return a.order<b.order;
        }
        else{
            return a.grade<b.grade;
        }
    }
    int main(){
        int n;
        int func;
        cin>>n>>func;
        student stu[n];
        for(int i=0;i<n;i++){
            cin>>stu[i].name>>stu[i].grade;
            stu[i].order=i;
        }
        if(func==0){
            sort(stu,stu+n,compare1);
        }else{
            sort(stu,stu+n,compare2);
        }
        for(int i=0;i<n;i++){
            cout<<stu[i].name<<" "<<stu[i].grade<<endl;
        }
        return 0;
    }
    

    6.二分查找

    在查找次数很多的情况下,二分查找优于线性查找
    二分查找需要先排序,再查找;
    while(left<=right){
    注意二分法退出循环的条件。
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int BinarySearch(int a,int num[],int n){
        int left=0;
        int right=n-1;
        int mid=(left+right)/2;
        while(left<=right){
            if(num[mid]==a){
                return 1;
            }
            else if(num[mid]<a){
                left=mid+1;
            }else{
                right=mid-1;
            }
            mid=(left+right)/2;
        }
        return 0;
    }
    int main(){
        int n,m;
        while(cin>>n){
            int arr[n];
            for(int i=0;i<n;i++){
                cin>>arr[i];
            }
            sort(arr,arr+n);
            cin>>m;
            int num,target;
            for(int i=0;i<m;i++){
                cin>>num;
                target=BinarySearch(num,arr,n);
                if(target==1){
                    cout<<"YES"<<endl;
                }else{
                    cout<<"NO"<<endl;
                }
            }
        }
        return 0;
    }

    7.字符串string

    string

    插入删除

    长度
    #include<iostream>
    #include<string>
    using namespace std;
    int main(){
        string str="Hello World!";
        int n=str.length();//长度
        str.insert(0, "zq");//把"zq"插入到位置"0" 
        //cout<<str;
        str.erase(0,2);//删除从位置0开始的2个字符 
        str.clear();
    	cout<<str; 
        
        return 0;
    }

    常用函数

    find()
    没找到返回-1
    substr()
    下标从0开始
    #include<iostream>
    #include<string>
    using namespace std;
    int main(){
        string str="Hello World!";
        int found=str.find("Hello");
    	cout<<found<<endl; 
        string str1=str.substr(0,5);
        cout<<str1;
        return 0;
    }
    

    常见应用

    • 字符串处理
    巧用ASCII码计算
    #include<iostream>
    #include<string>
    using namespace std;
    int main(){
        string str1,str2;
        cin>>str1>>str2;
        int len1,len2;
        len1=str1.length();
        len2=str2.length();
        int sum=0;
        for(int i=0;i<len1;i++){
            for(int j=0;j<len2;j++){
                sum=sum+(str1[i]-'0')*(str2[j]-'0');
            }
        }
        cout<<sum;
        return 0;
    }
    
     
    • getline()可以获取一行带空格的字符串,cin>>str遇到空格就会停止输入
    #include<iostream>
    #include<string>
    #include<algorithm>
    using namespace std;
    int main(){
        
        string str;
        int sym;
        while(getline(cin,str)){
            for(int i=0;i<str.length();i++){
                if(str[i]<='z'&&str[i]>='a'){
                    sym=str[i]-'a';
                    sym=(sym+1)%26;
                    str[i]='a'+sym;
                }
                if(str[i]<='Z'&&str[i]>='A'){
                    sym=str[i]-'A';
                    sym=(sym+1)%26;
                    str[i]='A'+sym;
                }
            }
            for(int i=0;i<str.length();i++){
                cout<<str[i];
            }
            cout<<endl;
        }
        
        return 0;
    }
    • 循环平移
    取余的方法P49
     
    • 字母出现次数统计
    用一个number数组统计各个出现的概率
    学会构造辅助数组
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cstdio>
    using namespace std;
    int num[128];//128个ASCII码
    int main(){
        string str1,str2;
        while(getline(cin,str1)){
            if(str1 == "#"){
                break;
            }
            getline(cin,str2);
            memset(num,0,sizeof(num));
            for(int i=0;i<str2.size();i++){
                num[str2[i]]++;
            }
            for(int i=0;i<str1.size();i++){
                printf("%c %d
    ",str1[i],num[str1[i]]);
            }
        }
        
        return 0;
    }
    • int的范围
    int有32位,2^32-1,注意int的范围使用
    注意pow函数,需要头文件<math.h>,pow(2,n);
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<math.h>
    using namespace std;
    int main(){
        string s;
        while(cin>>s){
            int sum=0;
            for(int i=0;i<s.length();i++){
                if(s[i]=='0')continue;
                sum=sum+(s[i]-'0')*(pow(2,s.length()-i)-1);
            }
            cout<<sum<<endl;
        }
    }
    • 首字母大写问题
    复习:注意getline函数的使用(C语言可以用gets)
    大写与小写字母的ASCII差值的使用
    #include<iostream>
    #include<string>
    #include<algorithm>
    using namespace std;
    int main(){
        string s;
        int p;
        while(getline(cin,s)){
            if(s[0]>='a'&&s[0]<='z'){
                p=s[0]+'A'-'a';
                s[0]=p;
            }
            for(int i=1;i<s.size();i++){
                if(s[i]==' '||s[i]=='	'||s[i]=='
    '||s[i]=='
    '){
                    i=i+1;
                    if(s[i]>='a'&&s[i]<='z'){
                        p=s[i]+'A'-'a';
                        s[i]=p;
                    }
                    else{
                        i=i-1;
                    }
                }
            }
            cout<<s;
        }
    }

     

    字符串匹配

    kmp算法

    重点理解next数组的求法
    #include<iostream>
    #include<string>
    #include<algorithm>
    //KMP算法 
    using namespace std;
    const int MAXM=10000;
    const int MAXN=1000000;
    
    int nextTable[MAXM];
    int pattern[MAXM];
    int text[MAXN];
    
    //创建next表
    void GetNextTable(int m){
    	int j=0;
    	nextTable[j]=-1;
    	int i=-1;
    	while(j<m){
    		if(i==-1||pattern[i]==pattern[j]){
    			i++;
    			j++;
    			nextTable[j]=i;
    		}else{
    			i=nextTable[i];
    		}
    	}
    } 
    int main(){
    	
    	
    	
    	return 0;
    } 

    8 数据结构一

    向量

    vector

    主要应用于不知道需要多大数组的方法

    #include<vector>
    push_back()
    pop_back()
    empty()
    size()
    insert()
    erase()
    clear()
    begin()
    end()
     
    #include<iostream>
    #include<string>
    #include<vector>
    using namespace std;
    
    vector<int>obj;
    
    int main(){
    	
    	for(int i=0;i<5;i++){
    		obj.push_back(i);
    	}
    	obj.insert(obj.begin(),3,15);
    	obj.pop_back();
    	for(int i=0;i<obj.size();i++){
    		cout<<obj[i]<<endl;
    	}
    	obj.erase(obj.begin()+5,obj.end());
    	vector<int>::iterator it;
    	for(it=obj.begin();it!=obj.end();it++){
    		cout<<*it<<" ";
    	}
    	obj.clear();
    	
    	return 0;
    }
    https://www.nowcoder.com/practice/ccc3d1e78014486fb7eed3c50e05c99d?tpId=60&tqId=29492&tPage=1&ru=/kaoyan/retest/1001&qru=/ta/tsing-kaoyan/question-ranking
    求因数
    #include<iostream>
    #include<vector>
    using namespace std;
    
    int s(int x){
        int sum=0;
        for(int i=1;i<=x/2;i++){
        	if(x%i==0){
        		sum=sum+i;
    		}
    	}
        //cout<<sum<<endl; 
        return sum;
    }
    int main(){
        vector<int>obj1;
        vector<int>obj2;
        for(int i=2;i<=60;i++){
            if(i==s(i)){
                obj1.push_back(i);
            }else if(i<s(i)){
                obj2.push_back(i);
            }
        }
        cout<<"E"<<":";
        for(int i=0;i<obj1.size();i++){
            cout<<" "<<obj1[i];
        }
        cout<<endl;
        cout<<"G"<<":";
        for(int i=0;i<obj2.size();i++){
            cout<<" "<<obj2[i];
        }
        return 0;
    }
    
    
    

    队列

    STL-queue
     
    #include<queue>
    queue<type>name
    empty()
    size()
    push()
    pop()
    front()
    back()
    队头删除元素
    队尾添加元素
     

    队列应用约瑟夫问题

    循环队列

    案例
     
    #include<iostream>
    #include<queue>
    #include<algorithm>
    using namespace std;
    //模拟循环队列 
    int main(){
    	int n,p,m;
    	while(cin>>n>>p>>m){
    		if(n==0&&p==0&&m==0){
    			break;
    		}
    		queue<int>children;
    		for(int i=1;i<=n;i++){
    			children.push(i);//加入编号 
    		}
    		for(int i=1;i<p;i++){
    			children.push(children.front());
    			children.pop();//把编号为p的放在第一位 
    		}
    		while(!children.empty()){
    			for(int i=1;i<m;i++){//m-1个小孩重新入队 
    				children.push(children.front());
    				children.pop();
    			}
    			if(children.size()==1){
    				cout<<children.front()<<endl;
    			}else{
    				cout<<children.front()<<',';
    			}
    			children.pop();
    		} 
    	} 
    	
    	return 0;
    }

    stack
    stack<typename>name
    empty()
    size()
    push()
    back()
    top()和队列不同的地方,只能访问栈顶

    栈的应用

    无法实现确定存放容器的大小

    逆序输出

    注意:int最大值:2^31-1=214748364(9位)
    long long 最大值 2^64-1=9223372036854775807(19位)
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<stack>
    using namespace std;
    
    stack<long long>st;//用long long
    int main(){
        int n;
        while(cin>>n){
            for(int i=0;i<n;i++){
                long long num;
                cin>>num;
                st.push(num);
            }
            while(!st.empty()){
                cout<<st.top()<<" ";
                st.pop();
            }
            cout<<endl;
        }
        
        
        
        return 0;
    }


    括号匹配

    括号左右匹配

    表达式求值

    简单计算器
    用栈解决
    数据栈
    符号栈
    #include<iostream>
    #include<algorithm>
    #include<stack>
    #include<string>
    #include<iomanip>
    using namespace std;
    
    int pr(char c){//优先级顺序 
    	if(c=='#'){
    		return 0;
    	}else if(c=='$'){
    		return 1;
    	}else if(c=='+'||c=='-'){
    		return 2;
    	}else{
    		return 3;
    	}
    } 
    //取参与运算的数据 
    double getNumber(string s,int &index){
    	double number=0;
    	while(s[index]>='0'&&s[index]<='9'){
    		number=number*10+s[index]-'0';
    		index++;
    	}
    	return number;
    	cout<<1;
    	cout<<number<<endl; 
    }
    //计算
    double Calculate(double x,double y,char op){
    	double result=0;
    	if(op=='+'){
    		result=x+y;
    	}else if(op=='-'){
    		result=x-y;
    	}else if(op=='*'){
    		result=x*y;
    	}else if(op=='/'){
    		result=x/y;
    	}
    	return result;
    } 
    int main(){
    	string str;
    	while(getline(cin,str)){
    		if(str=="0"){
    			break;
    		}
    		int index=0;//字符串处理定位
    		stack<double>data;//数据栈
    		stack<char>op;//运算符栈
    		str=str+'$';
    		op.push('#');
    		//cout<<str; 
    		while(index<str.size()){
    			if(str[index]==' '){
    				index++;
    			}else if(str[index]>='0'&&str[index]<='9'){
    				data.push(getNumber(str,index));
    				//cout<<str; 
    				//cout<<data.top();
    				//cout<<"zq";
    			}else{
    				if(pr(op.top())<pr(str[index])){
    					op.push(str[index]);
    					index++;
    					//cout<<str; 
    				}else{
    					double y=data.top();//x和y顺序不能反 
    					data.pop();
    					double x=data.top();
    					data.pop();
    					//cout<<str; 
    					data.push(Calculate(x,y,op.top()));
    					op.pop();
    					//cout<<str; 
    				}
    			}
    		} 
    		//cout<<op.top(); 
    		cout<<fixed<<setprecision(2)<<data.top()<<endl;
    	}
    	
    	return 0;
    } 
    

    9 数学问题

    进制转换

    字符串的加减乘除
    //author:Q_Zhang
    #include<iostream>
    #include<string>
    #include<vector>
    using namespace std;
    string Divide(string str,int x){//字符串除法
        int remainder=0;   //余数 
        for(int i=0;i<str.size();i++){
            int num=remainder*10+str[i]-'0';//每一步余数与下一位的组合
            str[i]=num/x+'0';//除法运算
            remainder=num%x;//在这一位的余数
        }
        int pos=0;
        cout<<remainder<<endl;
        while(str[pos]=='0'){//去除产生多余的0
        	pos++;
    	}
    	return str.substr(pos);
    }
    int main(){
        string x;
        cin>>x;
        x=Divide(x,5); 
        cout<<x;
        return 0;
        
    }

    最大公约数,最小公倍数

    辗转相除法求最大公约数
    两数乘积除以最大公约数即为最小公倍数

    非递归
    #include<iostream>
    using namespace std;
    
    int max(int a,int b){
        int r;
        if(a<b){
            r=a;
            a=b;
            b=r;
        }
        r=a%b;
        while(r!=0){
            a=b;
            b=r;
            r=a%b;
        }
        return b;
    }
    int main(){
        int m,n,result;
        while(cin>>m>>n){
            result=max(m,n);
            cout<<result<<endl;
        }
        
        return 0;
    }
    递归很简单自行查阅
     

    质数

    素数筛法

    找到一个素数,就将它所有倍数均标记为非素数,则判定其为素数,并标记它的所有倍数为非素数,然后继续遍历
    #include<iostream>
    #include<vector>
    using namespace std;
    
    const int MAXN=10001;
    vector<int>prime;
    bool isPrime[MAXN];
    
    void Init(){
        for(int i=0;i<MAXN;i++){
            isPrime[i]=true;
        }
        isPrime[0]=false;
        isPrime[1]=false;
        for(int i=2;i<MAXN;i++){
            if(!isPrime[i]){
                continue;
            }
            prime.push_back(i);
            for(int j=i*i;j<MAXN;j=j+i){
                isPrime[j]=false;
            }
        }
    }
    
    int main(){
        Init();
        int n;
        bool output=false;
        while(cin>>n){
            for(int i=0;i<prime.size();i++){
                if(prime[i]>=n){
                    break;
                }
                else if(prime[i]%10==1){
                    output=true;
                    cout<<prime[i]<<" ";
                }
            }
            if(!output){
                cout<<-1;
            }
            cout<<endl;
        }
        
        return 0;
    }
     

    质数判断

    #include<iostream>
    #include<cmath>
    using namespace std;
    
    bool Judge(int x){
        if(x<2){
            return false;
        }
        int bound=sqrt(x);
        for(int i=2;i<=bound;i++){
            if(x%i==0){
                return false;
            }
        }
        return true;
    }
    int main(){
        int n;
        bool s;
        while(cin>>n){
            s=Judge(n);
            if(s){
                cout<<"yes"<<endl;
            }else{
                cout<<"no"<<endl;
            }
        } 
        return 0;
    }

    分解质因数

    #include<iostream>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    int main(){
        int n;
        while(cin>>n){
            int num=0;
            int bound=sqrt(n);
            for(int i=2;i<=bound;i++){
                while(n%i==0){
                    num++;
                    n=n/i;
                }
            }
            if(n!=1)num++;//特别注意:如果n为质数的情况下
            cout<<num<<endl;
        }
        return 0;
    }

    快速幂

    核心思想:将指数化为2进制数,1对应的位是快速求幂的分解的指数

    #include<iostream>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    
    int Fast(int a,int b,int mod){
    	int answer=1;
    	while(b!=0){ //核心思想:转化为2进制 
    		if(b%2==1){
    			answer=answer*a;
    			answer=answer%mod;
    		} 
    		b=b/2;
    		a=a*a;
    		a=a%mod;
    		
    	}
    	return answer;
    }
    int main(){
    	int a,b;
    	while(cin>>a>>b){
    		if(a==0&&b==0){
    			break;
    		}
    		cout<<Fast(a,b,1000)<<endl;
    	}
    	return 0;
    } 
     
    矩阵快速幂
    原理同快速幂,初始状态为单位矩阵

    大整数的加减乘除 重要

    #include<iostream>
    #include<string>
    #include<vector>
    #include<algorithm>
    using namespace std;
    void Switch(string &a,string &b){
        string c=a;
        a=b;
        b=c;
    }
    
    int main(){
        string a,b;
        int len1,len2,p;
        while(cin>>a>>b){
        	vector<int>obj;
            len1=a.size();
            len2=b.size();
            if(len2<len1){
                Switch(a, b);
            }
            int remain=0;
            int i=a.size()-1;//特别注意:交换过后需要重新求解长度
            int j=b.size()-1;
            for(;i>=0;i--,j--){
                p=a[i]-'0'+b[j]-'0'+remain;
                if(p>=10){
                    remain=1;
                    p=p-10;
                    obj.push_back(p);
                }else{
                    obj.push_back(p);
                    remain=0;
                }
            }
            for(;j>=0;j--){
            	p=b[j]-'0'+remain;
            	if(p>=10){
                    remain=1;
                    p=p-10;
                    obj.push_back(p);
                }else{
                    obj.push_back(p);
                    remain=0;
                }
    		}
    		if(remain==1){
    			obj.push_back(1);
    		}
    		for(int k=obj.size()-1;k>=0;k--){
    			cout<<obj[k];
    		}
    		obj.clear();
    		cout<<endl;
        }
        
        return 0;
    }
    第二种思路:进位统一处理
    #include<iostream>
    #include<string>
    #include<vector>
    #include<algorithm>
    using namespace std;
    void Switch(string &a,string &b){
        string c=a;
        a=b;
        b=c;
    }
    
    int main(){
        string a,b;
        int len1,len2,p;
        while(cin>>a>>b){
        	vector<int>obj;
            len1=a.size();
            len2=b.size();
            if(len2<len1){
                Switch(a, b);
            }
            int remain=0;
            int i=a.size()-1;
            int j=b.size()-1;
            for(;i>=0;i--,j--){
                p=a[i]-'0'+b[j]-'0'+remain;
                if(p>=10){
                    remain=1;
                    p=p-10;
                    obj.push_back(p);
                }else{
                    obj.push_back(p);
                    remain=0;
                }
            }
            for(;j>=0;j--){
            	p=b[j]-'0'+remain;
            	if(p>=10){
                    remain=1;
                    p=p-10;
                    obj.push_back(p);
                }else{
                    obj.push_back(p);
                    remain=0;
                }
    		}
    		if(remain==1){
    			obj.push_back(1);
    		}
    		for(int k=obj.size()-1;k>=0;k--){
    			cout<<obj[k];
    		}
    		obj.clear();
    		cout<<endl;
        }
        
        return 0;
    }
    乘法稍微改一下就成
    #include<iostream>
    #include<string>
    using namespace std;
    int main(){
        string a,b;
        int len1,len2,len3,i,j,k=0;
        cin>>a;
        cin>>b;
        len1=a.length();
        len2=b.length();
        len3=len1+len2;
        int aa[len1+1]={0},bb[len2+1]={0},cc[len3+1]={0};
        for(i=1;i<=len1;i++){
            aa[i]=a[len1-i]-'0';
        }
        for(i=1;i<=len2;i++){
            bb[i]=b[len2-i]-'0';
        }
        for(i=1;i<=len1;i++){
            for(j=1;j<=len2;j++){
                cc[i+j-1]=cc[i+j-1]+aa[i]*bb[j]; //小技巧要注意
            }
        }
        for(i=1;i<=len3;i++){
            cc[i+1]=cc[i+1]+cc[i]/10;
            cc[i]=cc[i]%10;
        }
        while(len3>0&&cc[len3]==0){
            len3--;
        }
        if(len3==0){
            cout<<0<<endl;
        }
        else{
            for(i=len3;i>0;i--){
                cout<<cc[i];
            }
            cout<<endl;
        }
        return 0;
    }

    10 贪心策略

    最优时间分配:
    选择结束时间最早的
     
     

    11 递归与分治

    1.子问题要与原始问题相同
    2.不能无限制调用本身,必须有个递归出口
     
    阶乘可以用递归

    汉诺塔

    后期总结补充
     

    分治法

    斐波那契数列
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    int Fibonacci(int n){
    	if(n==1||n==0){
    		return n;
    	}else{
    		return Fibonacci(n-1)+Fibonacci(n-2);
    	}
    }
    
    int main(){
    	int n;
    	while(cin>>n){
    		cout<<Fibonacci(n)<<endl;
    	}
    } 
    子树有多少个节点问题
     
     

    12 搜索(难度较大,掌握后level上升一个台阶)

    广度优先搜索BFS

     
    需要有访问标记
    玛雅密码

    深度优先搜索DFS

    八皇后问题
     
     

    13 数据结构二

     

    二叉树的遍历

    #include<iostream>
    #include<algorithm>
    #include<queue>
    using namespace std;
    
    struct TreeNode{
    	int data;
    	TreeNode *leftChild;
    	TreeNode *rightChild;
    }; 
    //前序遍历
    void PreOrder(TreeNode *root){
    	if(root==NULL){
    		return;
    	}
    	cout<<root->data;
    	PreOrder(root->leftChild);
    	PreOrder(root->rightChild); 
    	return;
    } 
    //中序遍历 
    void InOrder(TreeNode *root){
    	if(root==NULL){
    		return;
    	}
    	InOrder(root->leftChild);
    	cout<<root->data;	
    	InOrder(root->rightChild); 
    	return;
    }
    //后序遍历
    void PostOrder(TreeNode *root){
    	if(root==NULL){
    		return;
    	}
    	PostOrder(root->leftChild);
    	PostOrder(root->rightChild); 
    	cout<<root->data;
    	return;
    }
    //层序遍历
    void LevelOrder(TreeNode *root){
    	queue<TreeNode *>myQueue;
    	if(root!=NULL){
    		myQueue.push(root);
    	}
    	while(!myQueue.empty()){
    		TreeNode *current=myQueue.front();
    		myQueue.pop();
    		cout<<current->data;
    		if(current->leftChild!=NULL){
    			myQueue.push(current->leftChild);
    		}
    		if(current->rightChild!=NULL){
    			myQueue.push(current->rightChild);
    		}
    	}
    	return;
    } 
    int main(){
    	
    
    	
    	return 0;
    } 

    通过先序遍历和中序遍历构建树

    https://www.nowcoder.com/questionTerminal/6e732a9632bc4d12b442469aed7fe9ce
    (未理解)
    #include<iostream>
    #include<algorithm>
    using namespace std;
    struct TreeNode{
    	char data;
    	TreeNode *leftChild;
    	TreeNode *rightChild;
        TreeNode(char c): data(c),leftChild(NULL),rightChild(NULL){}
    }; 
    TreeNode *Build(string str1,string str2){
        if(str1.size()==0){
            return NULL;
        }
        char c = str1[0];
        TreeNode *root=new TreeNode(c);
        int posion=str2.find(c);
        root->leftChild=Build(str1.substr(1,posion),str2.substr(0,posion));
        root->rightChild=Build(str1.substr(posion+1), str2.substr(posion+1));
        return root;
    
    }
    void PostOrder(TreeNode *root){
    	if(root==NULL){
    		return;
    	}
    	PostOrder(root->leftChild);
    	PostOrder(root->rightChild); 
    	cout<<root->data;
    	return;
    }
    int main(){
        string str1,str2;
        while(cin>>str1>>str2){
            TreeNode *root = Build(str1,str2);
            PostOrder(root);
            cout<<endl;
        }
        return 0;
    }

    二叉排序树

    https://www.nowcoder.com/practice/30a0153649304645935c949df7599602?tpId=69&tqId=29654&tPage=1&ru=/kaoyan/retest/11002&qru=/ta/hust-kaoyan/question-ranking
    (weilijie)
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    struct TreeNode{
        int data;
        TreeNode *leftNode;
        TreeNode *rightNode;
        TreeNode(int x): data(x),leftNode(NULL),rightNode(NULL){}
    };
    TreeNode *Insert(TreeNode *root,int x,int father){
        if(root==NULL){
            root=new TreeNode(x);
            cout<<father<<endl;
        }else if(x<root->data){
            root->leftNode=Insert(root->leftNode,x,root->data);
        }else{
            root->rightNode=Insert(root->rightNode,x,root->data);
        }
        return root;
    }
    int main(){
        int n;
        while(cin>>n){
            TreeNode *root=NULL;
            for(int i=0;i<n;i++){
                int x;
                cin>>x;
                root=Insert(root,x,-1);
            }
            
        }
        return 0;
        
        return 0;
    }
     

    优先队列

    #include<queue>
    优先队列的典型应用:
    priority_queue<int>myQueue;
    默认是大顶堆
     

    哈夫曼树

    哈夫曼树需要改为小顶堆,用greater
    priority_queue<int,vector<int>,greater<int>>myQueue;
     
    #include<iostream>
    #include<queue>
    using namespace std;
    int main(){
        int n;
        while(cin>>n){
            priority_queue<int,vector<int>,greater<int>>myQueue;
            while(n--){
                int x;
                cin>>x;
                myQueue.push(x);
            }
            int result=0;
            while(myQueue.size()>1){
                int p=myQueue.top();
                myQueue.pop();
                int q=myQueue.top();
                myQueue.pop();
                result=result+p+q;
                myQueue.push(p+q);
            }
            cout<<result<<endl;
        }
        return 0;
    }

    散列表

    #include<map>
    
    map<int,int>name;
    
    map.empty()
    map.size()
    map.insert();
    map.erase();
    
    []
    at()
    
    find()
    clear()
    
    begin()
    end()
    
     

    散列表操作

    #include<iostream>
    #include<map>
    #include<string>
    using namespace std;
    
    map<string,int>myMap;
    
    int main(){
    	myMap["em"]=67;
    	myMap.insert(pair<string,int>("bob",72));
    	cout<<myMap.size()<<endl;
    	cout<<myMap["bob"]<<endl;
    	cout<<myMap.at("em")<<endl;
    	myMap.erase("em");
    	map<string,int>::iterator it;
    	for(it = myMap.begin();it!=myMap.end();it++){
    		
    		cout<<it->first<<' '<<it->second<<endl;
    	}
    	myMap.clear();
    	it=myMap.find("bob");
    	if(it==myMap.end()){
    		cout<<"没找到";
    	}
    	return 0;
    	
    	
    } 

    字串计算
    注意substr()的使用
    #include<iostream>
    #include<map>
    #include<string>
    using namespace std;
    
    int main(){
        string str;
        while(cin>>str){
            map<string,int>count;
            for(int i=0;i<=str.size();i++){
                for(int j=0;j<i;j++){
                    string key=str.substr(j,i-j);
                    count[key]++;
                    
                }
            }
            map<string,int>::iterator it;
            for(it=count.begin();it!=count.end();it++){
                if(it->second>1){
                    cout<<it->first<<" "<<it->second<<endl;
                }
            }
        }
        
        return 0;
    }
    

    14 图论(really difficult)学会再提升一个level

     

    最小生成树


    最短路径 迪杰斯特拉算法


    拓扑排序


    关键路径

    后续更新
    (水平有限)
     
     
     

    15 动态规划

     
     

    斐波那契额数列的变体

    上楼梯问题
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    const int MAXN = 92;
    long long dp[MAXN];
    int main(){
        dp[0]=0;
        dp[1]=1;
        for(int i=2;i<MAXN;i++){
            dp[i]=dp[i-1]+dp[i-2];
        }
        int n;
        while(cin>>n){
            cout<<dp[n+1]<<endl;
        }
        return 0;
    }

    最大连续子序列和

    https://www.nowcoder.com/questionTerminal/df219d60a7af4171a981ef56bd597f7b

    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    const int MAXN=1000000;
    
    long long arr[MAXN];
    long long dp[MAXN];
    
    long long Max(int n){
        long long maxs=0;
        for(int i=0;i<n;i++){
            if(i==0){
                dp[i]=arr[i];
            }else{
                dp[i]=max(arr[i],dp[i-1]+arr[i]);
            }
            maxs=max(maxs,dp[i]);
        }
        return maxs;
    }
    
    
    int main(){
        int n;
        while(cin>>n){
            for(int i=0;i<n;i++){
                cin>>arr[i];
            }
            long long answer=Max(n);
            cout<<answer<<endl;
        }
        
        return 0;
    }
    二维:
    https://www.nowcoder.com/practice/1c5fd2e69e534cdcaba17083a5c56335?tpId=61&tqId=29506&tPage=1&ru=/kaoyan/retest/1002&qru=/ta/pku-kaoyan/question-ranking

    最长递增子序列

    设置一个dp[ ]表示以A[ i ]作为末尾的最长递归子序列长度,则最长递增子序列长度是dp[ ]数组中的最大值
    两种情况:
    A[i]之前的元素都比她大,则dp[ i ]=1;
    之前的元素比它小
    #include<iostream>
    using namespace std;
    
    const int MAXN=1000;
    
    int arr[MAXN];
    int dp[MAXN];
    
    int main(){
        int n;
        while(cin>>n){
            for(int i=0;i<n;i++){
                cin>>arr[i];
            }
            int answer=0;
            for(int i=0;i<n;i++){
                dp[i]=arr[i];
                for(int j=0;j<i;j++){
                    if(arr[j]<arr[i]){
                        dp[i]=max(dp[i],dp[j]+arr[i]);
                    }
                }
                answer=max(answer,dp[i]);
            }
            cout<<answer<<endl;
        } 
        return 0;
    }

    最长公共子序列

    dp[ i ] [ j ]表示以S1[i]和S2[j]作为末尾的最长公共子序列长度
    s1[i]==s2[j]  dp[i][j]=dp[i-1][j-1]+1;
    
    s1[i]!=s2[j] dp[i][j]=max(dp[i][j-1],dp[i-1][j]);
     
     
    #include<iostream>
    #include<cstring>
    using namespace std;
    
    const int MAXN=1001;
    
    char s1[MAXN];
    char s2[MAXN];
    
    int dp[MAXN][MAXN];
    
    int main(){
        while(scanf("%s%s",s1+1,s2+1)!=EOF){
            int n=strlen(s1+1);
            int m=strlen(s2+1);
            for(int i=0;i<=n;i++){
                for(int j=0;j<=m;j++){
                    if(i==0||j==0){
                        dp[i][j]=0;
                        continue;
                    }
                    if(s1[i]==s2[j]){      
                        dp[i][j]=dp[i-1][j-1]+1;
                    }else{
                        dp[i][j]=max(dp[i][j-1],dp[i-1][j]);
                    }
                }
            }
            cout<<dp[n][m];
        }
        
        return 0;
    }
     

    背包问题

    0-1背包

    (未理解)欢迎交流
    (记住)
    #include<iostream>
    using namespace std;
    
    const int MAXN=1001;
    int v[MAXN];//价值
    int w[MAXN];//重量
    int dp[MAXN];
    
    int main(){
        int n,m;
        while(cin>>m>>n){
            for(int i=0;i<n;i++){
                cin>>w[i]>>v[i];
            }
            for(int i=0;i<=m;i++){//初始化
                dp[i]=0;
            }
            for(int i=0;i<n;i++){
                for(int j=m;j>=w[i];j--){  //特别注意要逆序遍历
                    dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
                }
            }
            cout<<dp[m]<<endl;
        }
        return 0;
    }


    完全背包

    与0-1背包不同,每种物品可以取不止一件
    (未理解)
    只需将0-1背包的逆向改为正向即可
     

    其他问题

    整数拆分
     
    #include<iostream>
    using namespace std;
    
    const int MAXN=1000001;
    int dp[MAXN];
    
    int main(){
    	dp[0]=1;
    	dp[1]=1;
    	for(int i=2;i<=MAXN;i++){
    		if(i%2==0){
    			dp[i]=(dp[i-1]+dp[i/2])%1000000000;
    		}
    		else{
    			dp[i]=dp[i-1];
    		}
    		
    	}
    	int n;
    	while(cin>>n){
    		cout<<dp[n]<<endl;
    	}
    	return 0;
    }

                                                                                                                                                                                                                                                                                    2020-9-6于南京NUIST
     
     
  • 相关阅读:
    《那些年啊,那些事——一个程序员的奋斗史》——48
    《那些年啊,那些事——一个程序员的奋斗史》——49
    《那些年啊,那些事——一个程序员的奋斗史》——47
    《那些年啊,那些事——一个程序员的奋斗史》——46
    《那些年啊,那些事——一个程序员的奋斗史》——46
    如何面对单调重复的任务
    几则关于glibc的locale的笔记
    欢迎大家加入Linux Mobile Research圈子
    Idle函数的三大用途
    几则gdb使用技巧
  • 原文地址:https://www.cnblogs.com/zq-dmhy/p/13621773.html
Copyright © 2011-2022 走看看