计算机考研复试上机算法学习

计算机考研复试上机算法学习

这篇博客是博主在准备可能到来的线下上机复试基于王道机试指南的学习,将各道习题链接和代码记录下来,这篇博客权且当个记录。

文章目录

1.STL容器学习

1.1 vector动态数组

vector是C加加语言中的动态数组,内存空间是连续的,适用于插入删除操作少,随机访问频繁的场景。

#定义vector动态数组
vector<int> a;
vector<int> a;
a.push_back(500);//插入数据
a.insert(a.begin(),99);//在对应元素前面插入99
a.erase(a.begin()+1);//删除对应位置得到数据
cout<<a[1];//直接按照数组访问方式来访问
sort(a.begin(),a.end());
a.pop_back();//删除数组末尾元素
a.erase(a.begin()+1,a.begin()+2);//删除区间[i,j)之间的元素 
a.clear()//清空数组内部元素
reverse(a.bgin(),a.end())//反转数组元素
1.1.1 完数VS盈数

完数VS盈数_牛客题霸_牛客网 (nowcoder.com)

本题按照题意即可,主要是使用动态数组处理不定元素的数组较为方便

#include <iostream>
#include<vector>
using namespace std;

int main() {
    vector <int>e;
    vector<int> g;
    for(int nums=2;nums<=60;nums++){
        int res =0;
        for(int i=1;i<nums;i++){
            if(nums%i==0){
                res+=i;
            }
        }
        if(res == nums) e.push_back(nums);
        else{
            if(res>nums) g.push_back(nums);
        }
    }
    cout<<"E:";
    for(int i=0;i<e.size();i++){
       cout<<" "<<e[i];
    }
    cout<<endl;
    cout<<"G:";
    for(int i=0;i<g.size();i++){
       cout<<" "<<g[i];
    }
    cout<<endl;

}

1.2 stack栈

stack<int> st;
st.push(1);//插入元素到栈顶
    cout<<st.top();//访问元素的栈顶
    cout<<endl<<st.size();
    st.pop();//删除栈顶元素
    if(st.empty())
        cout<<"empty";
1.2.1 逆序输出

Zero-complexity Transposition_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<stack>
using namespace std;

int main() {
    int n;
    while(cin>>n){
        stack<int> s;
        int k;
        for(int i=0;i<n;i++){
            cin>>k;
            s.push(k);
        }
        while(!s.empty()){
            cout<<s.top()<<" ";
            s.pop();
        }
        cout<<endl;
    }
}
1.2.2 后缀运算符

简单计算器_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<stack>
#include<string>
#include <map>
using namespace std;
double calculate(double a, double b, char op) {
    double n1 = double(a);
    double n2 = double(b);
    switch (op) {
        case'+':
            return n1 + n2;
            break;
        case '-':
            return n1 - n2;
            break;
        case '*':
            return n1 * n2;
            break;
        case '/':
            return n1 / n2;
            break;
    }
    return 0;
}

double GetNumber(string str, int& index) {
    double number = 0;
    while (str[index] >= '0' && str[index] <= '9') {
        number = number * 10 + str[index] - '0';
        index++;
    }
    return number;
}

int main() {
    string str;
    map<char, int> m;
    m['+'] = 1;
    m['-'] = 1;
    m['*'] = 2;
    m['/'] = 2;

    while (getline(cin, str)) {
        if (str == "0") break;
        stack<double> s1;
        stack<char> op;
        for (int i = 0; i < str.size(); i++) {
            if (str[i] >= '0' && str[i] <= '9') {
                s1.push(GetNumber(str, i));
            } else {
                if (str[i] == ' ')
                    continue;
                else {

                    if (op.empty() || m[op.top()] < m[str[i]]) {
                        op.push(str[i]);
                    } else {
                        while (m[op.top()] >= m[str[i]]) {
                            double b = s1.top();
                            char ch = op.top();
                            op.pop();

                            s1.pop();
                            double a = s1.top();
                            s1.pop();
                            s1.push(calculate(a, b, ch));
                            if (op.empty()) break;
                        }
                        op.push(str[i]);

                    }
                }
            }
        }
        while (!s1.empty()) {
            double b = s1.top();
            char ch = op.top();
            op.pop();
            s1.pop();
            double a = s1.top();
            s1.pop();
            s1.push(calculate(a, b, ch));
            if (s1.size() == 1) {
                printf("%0.2f\n", calculate(a, b, ch));
                break;
            }
        }
    }
}

计算表达式_牛客题霸_牛客网 (nowcoder.com)

另一个版本的后缀运算,代码大同小异

#include <iostream>
#include<stack>
#include<string>
#include <map>
using namespace std;
double calculate(double a, double b, char op) {
    double n1 = double(a);
    double n2 = double(b);
    switch (op) {
        case'+':
            return n1 + n2;
            break;
        case '-':
            return n1 - n2;
            break;
        case '*':
            return n1 * n2;
            break;
        case '/':
            return n1 / n2;
            break;
    }
    return 0;
}

double GetNumber(string str, int& index) {
    double number = 0;
    while (str[index] >= '0' && str[index] <= '9') {
        number = number * 10 + str[index] - '0';
        index++;
    }
    return number;
}

int main() {
    string str;
    map<char, int> m;
    m['+'] = 1;
    m['-'] = 1;
    m['*'] = 2;
    m['/'] = 2;

    while (getline(cin, str)) {
        if (str == "0") break;
        stack<double> s1;
        stack<char> op;
        for (int i = 0; i < str.size(); i++) {
            if (str[i] >= '0' && str[i] <= '9') {
                s1.push(GetNumber(str, i));
                i--;
            } else {
                if (str[i] == ' ')
                    continue;
                else {

                    if (op.empty() || m[op.top()] < m[str[i]]) {
                        op.push(str[i]);
                    } else {
                        while (m[op.top()] >= m[str[i]]) {
                            double b = s1.top();
                            char ch = op.top();
                            op.pop();

                            s1.pop();
                            double a = s1.top();
                            s1.pop();
                            s1.push(calculate(a, b, ch));
                            if (op.empty()) break;
                        }
                        op.push(str[i]);

                    }
                }
            }
        }
        while (!s1.empty()) {
            double b = s1.top();
            char ch = op.top();
            op.pop();
            s1.pop();
            double a = s1.top();
            s1.pop();
            s1.push(calculate(a, b, ch));
            if (s1.size() == 1) {
                printf("%d\n", int(calculate(a, b, ch)));
                break;
            }
        }
    }
}
1.2.3 堆栈的使用

堆栈的使用_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<stack>
using namespace std;

int main() {
    int n;
    int a,b,c;
    while (cin >> n) { // 注意 while 处理多个 case
         stack<int> s;
         char ch;
        for(int i=0;i<n;i++){
            cin>>ch;
            if(ch=='P') {
                cin>>a;
                s.push(a);
            }
            else if(ch=='A'){
                if(!s.empty()){
                    cout<<s.top()<<endl;
                }
                else{
                    cout<<'E'<<endl;
                }
            }

            else{
                if(!s.empty()) s.pop();
                else continue;

            }
        }
    }
}

1.3 queue队列

queue<int> s;//创造队列
 s.push(100);
 s.push(1000);
 s.pop();//删除队首元素
 //front访问对首位置,back访问队尾位置
 cout<<s.front()<<" "<<s.back();
1.3.1 实现循环队列来解决约瑟夫问题

约瑟夫问题I__牛客网 (nowcoder.com)

本题最重要的是怎么用队列实现正常的循环队列

#include <iostream>
#include<queue>
using namespace std;
class Joseph {
public:
    int getResult(int n, int m) {
        // write code here
        queue<int> p;
        for(int i=1;i<=n;i++){
            p.push(i);
        }
        while(!p.empty()){
            for(int i=1;i<m;i++){
                p.push(p.front());
                p.pop();
            }
            if(p.size()==1)
                return p.front();
            p.pop();
        }
    }
};

下面这个是书上的约瑟夫改版问题

#include <iostream>
#include<queue>
using namespace std;
int main() {
    int n,p,m;
    cin>>n>>p>>m;
    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();//出栈后再压入栈
    }
    while(!children.empty()){
        for(int i=1;i<m;i++){
            children.push(children.front());
            children.pop();

        }
        if(children.size()==1){
            cout<<children.front()<<endl;
        }
        else{
            cout<<children.front()<<" ";
        }
        children.pop();
    }

}

1.4 priority_queue优先队列

  • 头文件:include

  • priority_queue<Type, Container, Functional>,Type为元素类型;Container为容器类型,默认为vector,可选 项;Functional为比较方式,默认为降序排列。

  • 按照一定方式排列的队列,由二叉堆实现(根据 优先级形成大根堆),每次插入删除的时间复杂度为O(log2n)

  • 优先级最高的节点先出队

    //方式一
    priority_queue<int> pq;
    //方式二
    priority_queue<int,vector<int>,greater<int>> pq;//升序排列
    priority_queue<int,vector<int>,less<int>> pq;//降序排列
    pq.top();//队首元素
    pq.pop();//出队
    
    1.4.1 优先队列解决复数集合问题

    复数集合_牛客题霸_牛客网 (nowcoder.com)

    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<cstring>
    #include<string>
    
    using namespace std;
    struct Complex{
        int real;
        int imag;
        Complex(int a, int b): real(a),imag(b){}
        bool operator<(Complex c) const{
        if(real*real+imag*imag==c.real*c.real+c.imag*c.imag){
            return imag>c.imag;
        }
        else{
            return real*real+imag*imag<c.real*c.real+c.imag*c.imag;
    
        }
    
        }
    };
    
    int main() {
        int n;
        string str;
        while(cin>>n){
            priority_queue<Complex> pq;
            while(n--){
                cin>>str;
                if(str=="Pop"){
                    if(pq.empty()){
                        cout<<"empty"<<endl;
                    }
                    else{
                        Complex current  =pq.top();
                        pq.pop();
                        printf("%d+i%d\n",current.real,current.imag);
                        printf("SIZE = %d\n",pq.size());
                    }
                }
    
                else{
                    int a,b;
                    scanf("%d+i%d",&a,&b);
                    pq.push(Complex(a,b));
                    printf("SIZE = %d\n",pq.size());
                }
    
            }
        }
    }
    
    
1.4.2 优先队列解决哈夫曼树问题

搬水果_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<queue>
using namespace std;
int main() {
    int n;
    priority_queue<int, vector<int>, greater<int>>pq;
    while (cin >> n) { // 注意 while 处理多个 case
        if (n == 0) break;
        int a, b;
        while (n--) {
            cin >> a;
            pq.push(a);
        }
        int ans = 0;
        while (pq.size() > 1) {
            a = pq.top();
            pq.pop();
            b = pq.top();
            pq.pop();
            ans += a + b;
            pq.push(a + b);
        }
        cout << ans << endl;
    }
}

1.5 双向链表 list

双向链表的结点同时拥有指向后继和先驱指针的链表,内存空间可以是不连续的,插入和删除频繁,随机访问较少

list<int> mylist;
//要访问顺序容器和关联容器中的元素,需要通过“迭代器(iterator)”进行。迭代器是一个变量,相当于容器和操纵容器的算法之间的中介。\
//迭代器可以指向容器中的某个元素,通过迭代器就可以读写它指向的元素。从这一点上看,迭代器和指针类似。
list<int>::iterator it;//
int i;
for(i= 0;i<=5;i++){
    mylist.push_back(i);
    if(i==6) printf("yes");
}
cout<<endl;
for(it = mylist.begin();it!=mylist.end();it++){
    cout<<*it<<" ";//it相当于指针
}

1.6 set集合

C++中的集合由二叉搜索树(二叉查找树)实现,集合中的每个元素都只会出现一次,访问元素的时间复杂度为O(log2n)

//lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

//upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
set<int> a;//定义
set<int>::iterator it;
a.insert(100);//插入元素100
a.insert(100);
a.insert(101);
cout<<a.size();
//a.erase(100);//删除元素100
//a.clear();//清空
a.empty();//判断是否为空
cout<<a.size()<<endl;
it = a.find(100);//返回一个迭代器指向键值100
it = a.lower_bound(80);//返回键值不小于80的第一个元素
cout<<*it<<endl;
it = a.upper_bound(200);
cout<<*it<<endl;

1.7 map映射容器

  • 用红黑树实现,会对键值进行排序,在某些时候排序可以很方便解决某些问题(不排序的map称为unordered_map)

  • 如果没有查找到对应字符串的话value为字符串返回空串(“”),为数值时返回0,为指针时返回nullptr(C++推荐使用nullptr指针)

#include <cstdio>
#include <iostream>
#include <map>

using namespace std;

map <string,int> myMap;//内部按照关键字进行排序,底层为红黑树

int main(){
    //插入,添加元素
    myMap["Emma"]=67;
    myMap.insert(pair<string,int>("Bob",72));

    //查
    cout<<myMap["Emma"]<<endl;
    cout<<myMap.at("Bob")<<endl;

    //删除
    myMap.erase("Emma");

    map<string,int>::iterator it;
    for(it=myMap.begin();it!=myMap.end();it++){
        cout << it->first <<" "<<it->second<<endl;
    }

    //查找
    it=myMap.find("Bob");//返回迭代器
    if(it!=myMap.end()){
        return 0;//未找到
    }

    cout<<myMap.size();

    myMap.clear();//晴空

}


1.7.1 map的应用

查找学生信息_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<string>
#include<map>
using namespace std;
struct student {
    string name;
    string sex;
    int age;
    student(string name, string sex, int age): name(name), sex(sex), age(age) {}
};
int main() {
    int a, b;
    map<string, student*> m;
    string name, key, sex;
    int age;
    while (cin >> a ) { // 注意 while 处理多个 case
        if (a == 0) break;
        m.clear();
        while (a--) {
            cin >> key >> name >> sex >> age;
            m[key] = new student(name, sex, age);
        }
        cin >> b;
        student* tmp = nullptr;
        while (b--) {
            cin >> key;
            tmp = m[key];
            if (tmp == nullptr) {
                cout << "No Answer!" << endl;
            } else {
                cout << key << " " << tmp->name << " " << tmp->sex << " " << tmp->age << endl;
            }
        }
    }
}
1.7.2 统计字符串出现次数

子串计算_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<string>
#include<map>
using namespace std;

int main() {
    int a, b;
    map<string, int> m;
    string str;
    while (cin >> str) {
        m.clear();
        int n = str.size();
        //学会如何生成所有字串
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j < i; j++) {
                string sub = str.substr(j, i - j);
                m[sub] += 1;
            }
        }
        map<string, int>::iterator it;
        for (it = m.begin(); it != m.end(); it++) {
//        if(it->first=="") continue;
            if (it->second > 1)
                cout << it->first << " " << it->second << endl;
        }
    }
}
// 64 位输出请用 printf("%lld")

1.7.3 查询分数

统计同成绩学生人数_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<map>
using namespace std;

int main() {
    int n;
    map<int,int>m;
    int score;
    while (cin >> n) { // 注意 while 处理多个 case
        if(n==0) break;
        m.clear();
        while(n--){
            cin>>score;
            m[score]+=1;
        }
        cin>>score;
        cout<<m[score]<<endl;
    }
}
1.7.4 开门人 和关门人

开门人和关门人_牛客题霸_牛客网 (nowcoder.com)

本题利用map会给键值自动排序的功能即可解决

#include <iostream>
#include<map>
using namespace std;

int main() {
    int n;
    string code, start, end;
    map<string, string> m1;
    map<string, string> m2;
    while (cin >> n) { // 注意 while 处理多个 case
        while (n--) {
            cin >> code >> start >> end;
            m1[start] = code;
            m2[end] = code;
        }
        map<string, string>::iterator it;
        it = m1.begin();
        cout << it->second << " ";
        it = m2.end();
        it--;
        cout << it->second << endl;
    }
}/
    
1.7.5 谁是你的潜在朋友

谁是你的潜在朋友_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<map>
#include<vector>
using namespace std;
int main() {
    int n, m;
    map<int, int> table;
    vector<int> vec;
    while (cin >> n >> m) { // 注意 while 处理多个 case
        int num;
        while (n--) {
            cin >> num;
            vec.push_back(num);
            table[num] += 1;
        }
        for (int i = 0; i < vec.size(); i++) {
            int res = table[vec[i]] - 1;
            if (res == 0)cout << "BeiJu" << endl;
            else cout << res << endl;
        }
    }
}

1.8 sort排序函数

#include<algorithm>//需要引用<algorithm>头文件
bool compare(point p1, point p2){
    return p1.x>p2.x;//按x从大到小排序
}
list<point> l1;
sort(l1.begin(),l1.end(),compare);

1.9 next_permutation函数

STL提供的求再当前数组元素排列下求下一个排列组合的函数,每次使用next_permutation都会将元素按照排列重新放入对应位置,当按照字典序没有下一个排列的时候返回false否则返回true

    int num[3] = {1,2,3};
    do{
        cout<<num[0]<<" "<<num[1]<<" "<<num[2]<<endl;
    }while(next_permutation(num, num+3));
int num[3] = {3, 2, 1};
    do{
        cout<<num[0]<<" "<<num[1]<<" "<<num[2]<<endl;
    }while(prev_permutation(num, num+3));//prev与他返回则完全相反

2.算法学习

2.1 递归实现求元素的全排列

int num[3] = {3, 2, 1};
int Perm(int begin, int end){
    int i;
    if(begin == end){
        cout<<num[0]<<" "<<num[1]<<" "<<num[2]<<endl;
    }
    else{
        for(i=begin;i<=end;i++){
            swap(num[begin],num[i]);
            Perm(begin+1,end);
            swap(num[begin],num[i]);//交换回去开始下一波
        }
    }

}


int main()
{
    clock_t start,end;
    start = clock();
    Perm(0,2);
    end=clock();
    cout<<endl<<(double)(end - start)/CLOCKS_PER_SEC;
}

2.2 反序数

设N是一个四位数,它的9倍恰好是其反序数(例如:1234的反序数是4321),求N的值

#include <iostream>
using namespace std;
int reverse(int n){
    int revx =0;
    while(n!=0){
        revx*=10;
        revx+=n%10;
        n/=10;
    }
    return revx;
}

int main() {
    for(int i=0;i<=256;i++){
        int k=(i*i);
        if(k==reverse(k))
        cout<<k<<endl;
    }

2.3百鸡问题

百鸡问题_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
using namespace std;

void solve(int n){
    int i,j,k;
    for(i=0;i<=100;i++){
        for(j=0;j<=100-i;j++){//不能变成负数记得加上100-i
            k=100-i-j;
            if((i*15+j*9+k)<=n*3)
            printf("x=%d,y=%d,z=%d\n",i,j,k);
            
        }
    }
}

int main() {
    int n;
    while (cin >> n) { // 注意 while 处理多个 case
        solve(n);
    }
}

2.4 火鸡账单

Old Bill_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
using namespace std;
void solve(int n, int x, int y, int z){
    int maxSum =0;
    int maxi=0,maxj=0;
    for(int i=1;i<=9;i++){
        for(int j=0;j<9;j++){
            int sum=(i*10000+x*1000+y*100+z*10+j);
            if(sum%n==0){
                sum /=n;
                if(sum>maxSum){
                    maxSum = sum;
                    maxi=i;
                    maxj=j;
                }
            }
        }

    }
    if(maxSum == 0)
        cout<<0;
    else{
    printf("%d %d %d",maxi,maxj,maxSum);}
}
int main() {
    int n,x,y,z;
    while (cin >> n>>x>>y>>z) { // 注意 while 处理多个 case
        solve(n, x, y, z);
    }
}
// 64 位输出请用 printf("%lld")

2.5 今年的第几天

今年的第几天?_牛客题霸_牛客网 (nowcoder.com)

#include <cstdio>
#include <iostream>
using namespace std;

void solve(int year, int month, int day){
int data[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
//闰年的判断思路是如果年份不能被100整除,却能被4整除或400整除
if((year%100!=0&&year%4==0)||year%400==0) data[2] = 29;
int res =0;
for(int i=0;i<month;i++){
    res+=data[i];
}
res+=day;
cout<<res<<endl;
}

int main() {
    int year,month,day;
    while(scanf("%d %d %d",&year, &month, &day)!=EOF){
        solve(year, month, day);
    }

}
// 64 位输出请用 printf("%lld")

2.6打印日期

打印日期_牛客题霸_牛客网 (nowcoder.com)

#include <cstdio>
#include <iostream>
using namespace std;

void solve(int year, int date){
int data[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
if((year%100!=0&&year%4==0)||year%400==0) data[2] = 29;
int res =0;
int i=0;
for(i=1;i<=12;i++){
    if(date-data[i]>0)
    date -=data[i];
    else break;
}
printf("%d-%02d-%02d\n", year,i,date);

}

int main() {
    int year,day;
    while(cin>>year>>day){
        solve(year,  day);
    }

}
// 64 位输出请用 printf("%lld")

2.7 日期累加

日期累加_牛客题霸_牛客网 (nowcoder.com)

#include <cstdio>
#include <iostream>
using namespace std;

void solve(int year, int month, int day, int addDay) {
    int data[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    if ((year % 100 != 0 && year % 4 == 0) || year % 400 == 0) data[2] = 29;
    int res = 0;
    int i = 0;
    addDay+=day;
    do{

    for (i = month; i <= 12; i++) {
        if (addDay - data[i] > 0)
            addDay -= data[i];
        else break;
    }
    if(i>12) {
        month =1;
        year+=1;
        //在改变年份的时候记得修改2月的日期!!!!!
        if ((year % 100 != 0 && year % 4 == 0) || year % 400 == 0)          data[2] = 29;
        else data[2] =28;
        }
    
    }while(i>12);

    printf("%d-%02d-%02d\n", year, i, addDay);

}

int main() {
    int num;
    cin>>num;
    int year, month, day,addDay;
    for(int i=0;i<num;i++){
    cin >> year >>month>> day>> addDay;
    solve(year,  month, day, addDay);   
    }

}
// 64 位输出请用 printf("%lld")

2.8 日期差值_牛客题霸_牛客网 (nowcoder.com)

#include <cstdio>
#include <iostream>
using namespace std;

void solve(int year, int month, int day, int year2, int month2, int day2) {
    int data[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    if ((year % 100 != 0 && year % 4 == 0) || year % 400 == 0) data[2] = 29;
    int res = 0;
    int i = 0;
    res -= day;
    while (year != year2) {
        for (i = month; i <= 12; i++) {
            res += data[i];
        }
        if (year != year2) {
            month = 1;
            year += 1;
            //在改变年份的时候记得修改2月的日期!!!!!
            if ((year % 100 != 0 && year % 4 == 0) ||
                    year % 400 == 0)          data[2] = 29;
            else data[2] = 28;
        }

    }
    if (year == year2) {

        while (month < month2) {
            res += data[month];
            month++;
        }
        res += (day2 + 1);

    }
    cout << res;


    // printf("%d-%02d-%02d\n", year, i, addDay);

}

int main() {
    int num1, num2;
    while (cin >> num1 >> num2) {
        int year1 = num1 / 10000;
        num1 %= 10000;
        int month1 = num1 / 100;
        int day1 = num1 % 100;
        int year2 = num2 / 10000;
        num2 %= 10000;
        int month2 = num2 / 100;
        int day2 = num2 % 100;
        
        solve(year1, month1, day1, year2, month2, day2);

    }


}
// 64 位输出请用 printf("%lld")

2.9 Day of Week_牛客题霸_牛客网 (nowcoder.com)

#include <cstdio>
#include <iostream>
#include<string>
#include<map>
using namespace std;

int solve(int year, int month, int day, int year2, int month2, int day2) {
    int data[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    if ((year % 100 != 0 && year % 4 == 0) || year % 400 == 0) data[2] = 29;
    int res = 0;
    int i = 0;
    res -= day;
    while (year != year2) {
        for (i = month; i <= 12; i++) {
            res += data[i];
        }
        if (year != year2) {
            month = 1;
            year += 1;
            //在改变年份的时候记得修改2月的日期!!!!!
            if ((year % 100 != 0 && year % 4 == 0) ||
                    year % 400 == 0)          data[2] = 29;
            else data[2] = 28;
        }

    }
    if (year == year2) {

        while (month < month2) {
            res += data[month];
            month++;
        }
        res += (day2 + 1);

    }
    return res;


    // printf("%d-%02d-%02d\n", year, i, addDay);

}

int main() {
    int num1, num2;
    map<string, int> m;
    map<int, string> week;
//    一月 January,缩写Jan
//    二月 February,缩写Feb
//    三月 March,缩写Mar
//    四月 April,缩写Apr
//    五月 May,缩写May
//    六月 June,缩写Jun
//    七月 July,缩写Jul
//    八月 August,缩写Aug
//    九月 September,缩写Sep/Sept
//    十月 October,缩写Oct
//    十一月 November,缩写Nov
//    十二月 December,缩写Dec

    m["January"] = 1;
    m["February"] = 2;
    m["March"] = 3;
    m["April"] = 4;
    m["May"] = 5;
    m["June"] = 6;
    m["July"] = 7;
    m["August"] = 8;
    m["September"] = 9;
    m["October"] = 10;
    m["November"] = 11;
    m["December"] = 12;
    week[1] = "Monday";
    week[2] = "Tuesday";
    week[3] = "Wednesday";
    week[4] = "Thursday";
    week[5] = "Friday";
    week[6] = "Saturday";
    week[0] = "Sunday";
    int day, year;
    string month;
    while (cin >> day >> month >> year) {
        int m1 = m[month];
        int days = solve( 1969, 12, 29, year, m1, day);
        days %= 7;
        cout << week[days] << endl;

    }


}
// 64 位输出请用 printf("%lld")

2.10剩下的树_牛客题霸_牛客网 (nowcoder.com)

本题有一个很靠谱的思路,就是利用bool数组来处理可能重复处理的区间,暴力解法容易想到

#include <iostream>
using namespace std;
#define MAX 10001
int main() {
    bool tree[MAX];
    int i,j;
    int L,M;
    cin>>L>>M;
    int num =L+1;
    int left,right;
    for(i=0;i<=L;i++){
        tree[i]=true;
    }
    for(j=0;j<M;j++){
        cin>>left>>right;
        for(i=left;i<=right;i++){
            if(tree[i]){//如果以及被移除便不再处理
                tree[i] = false;
                num--;
            }
        }
    }
    cout<<num;
}
// 64 位输出请用 printf("%lld")

2.11xxx定律_牛客题霸_牛客网 (nowcoder.com)

本题按照题设做即可,不难

#include <iostream>
using namespace std;

void solve(int n){
    int num=0;
    while(n!=1){
        num++;
    if(n%2==0){
        n/=2;

    }
    else{
        n=n*3+1;
        n/=2;
    }

    }
    cout<<num<<endl;
}


int main() {
    int a;
    while (cin >> a ) { // 注意 while 处理多个 case
        solve(a);
    }
}
// 64 位输出请用 printf("%lld")

2.12 排序题

排序_牛客题霸_牛客网 (nowcoder.com)

//偷懒使用sort算法
#include <iostream>
#include<algorithm>
using namespace std;
#define MaxSize 101
int main() {
 int a[MaxSize]={0};
 int n;
 while(cin>>n){
 for(int i=0;i<n;i++){
     cin>>a[i];
 }
 sort(a,a+n);
 for(int i=0;i<n;i++){
     cout<<a[i]<<" ";
 }

 cout<<endl;
 }


}

2.13带学号的成绩排序问题

成绩排序_牛客题霸_牛客网 (nowcoder.com)

本题 尤其注意当成绩相同的时候应该要比较学号

#include <iostream>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;

typedef struct{
    int num;
    int score;
}students;

bool compare(students s1, students s2){
    if(s1.score==s2.score) 
        return s1.num<s2.num; 
    return s1.score<s2.score;

}

int main() {
    vector<students> vec;
    int num;
    while (cin >> num) { // 注意 while 处理多个 case
    for(int i=0;i<num;i++){
        students stu;
        cin>>stu.num>>stu.score;
        vec.push_back(stu);
    }
    sort(vec.begin(),vec.end(),compare);
    for(int i=0;i<vec.size();i++){
    cout<<vec[i].num<<" "<<vec[i].score<<endl;

    }
        
    }
}

2.14 考虑输入次序的学生成绩排序

成绩排序_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<queue>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;

typedef struct {
   string name;
    int score;
    int order;
} students;
//升序
bool compare1(students s1, students s2) {
    if(s1.score==s2.score)
        return s1.order<s2.order;//如果成绩相同按照次序先后排
    return s1.score < s2.score;

}
//降序
bool compare0(students s1, students s2) {
    if(s1.score==s2.score)
        return s1.order<s2.order;
    return s1.score > s2.score;


}

int main() {
    vector<students> vec;
    int num,method;
    while (cin >> num>>method) { // 注意 while 处理多个 case
        //cin>>method;
        vec.clear();//针对多次输入记得即使清空数据
        for (int i = 0; i < num; i++) {
            students stu;
            cin >> stu.name >> stu.score;
            stu.order=i;
            vec.push_back(stu);
        }
        if(method==0)
            sort(vec.begin(), vec.end(), compare0);
        else sort(vec.begin(), vec.end(), compare1);
        for (int i = 0; i < vec.size(); i++) {
            cout << vec[i].name << " " << vec[i].score << endl;
        }

    }
}

2.15特殊排序

特殊排序_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<queue>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;

typedef struct {
   string name;
    int score;
} students;
//升序
bool compare1(students s1, students s2) {
    return s1.score < s2.score;

}
//降序
bool compare0(students s1, students s2) {
    return s1.score > s2.score;

}

int main() {
    vector<students> vec;
    int num,method;
    while (cin >> num) { // 注意 while 处理多个 case
        cin>>method;
        for (int i = 0; i < num; i++) {
            students stu;
            cin >> stu.name >> stu.score;
            vec.push_back(stu);
        }
        if(method==0)
            sort(vec.begin(), vec.end(), compare0);
        else sort(vec.begin(), vec.end(), compare1);
        for (int i = 0; i < vec.size(); i++) {
            cout << vec[i].name << " " << vec[i].score << endl;
        }

    }
}

2.16 整数奇偶排序(简单)

整数奇偶排序_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;

bool compare(int a, int b){
    return a>b;
}

int main() {
    int b,i,j;
    int a[10]={0};
    vector<int> vec1;//存放奇数的数组
    vector<int> vec2;
    while (cin>>a[0]>>a[1]>>a[2]>>a[3]>>a[4]>>a[5]>>a[6]>>a[7]>>a[8]>>a[9]) { // 注意 while 处理多个 case
    for(i=0;i<10;i++){
        if(a[i]%2!=0)
        vec1.push_back(a[i]);
        else{
            vec2.push_back(a[i]);
        }
    }
    sort(vec1.begin(), vec1.end(),compare);
    sort(vec2.begin(),vec2.end());
    for(i=0;i<vec1.size();i++)
        cout<<vec1[i]<<" ";
    for(i=0;i<vec2.size();i++)
        cout<<vec2[i]<<" ";
    cout<<endl;
        
    }
}
// 64 位输出请用 printf("%lld")

2.17 小白鼠排序

小白鼠排队_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<queue>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;

typedef struct {
    string color;
    int weight;
} mouse;

bool compare1(mouse s1, mouse s2) {
    return s1.weight > s2.weight;

}

int main() {
    vector<mouse> vec;
    int num;
    while (cin >> num ) { // 注意 while 处理多个 case
        vec.clear();//针对多次输入记得即使清空数据
        for (int i = 0; i < num; i++) {
            mouse m;
            cin >> m.weight >> m.color;
            vec.push_back(m);
        }
        sort(vec.begin(), vec.end(),compare1);

        for (int i = 0; i < vec.size(); i++) {
            cout << vec[i].color << endl;
        }

    }
}

2.18 奥运排序问题

奥运排序问题_牛客题霸_牛客网 (nowcoder.com)

本题有一个很重要的技巧,就是在可能出现名次并列的情况使用逐个比较,而不是直接排序

#include <iostream>
#include<algorithm>
#include<vector>
using namespace std;
// 金牌总数 奖牌总数 金牌人口比例 奖牌人口比例
struct country {
    float gold;
    float reward;
    float numOfPeoples;
    float goldScale;
    float rewardScale;
    int rank[4] = {0};
};
int main() {
    int N, M;
    int id;
    vector<country> vec;
    vector<country> resVec;
    while (cin >> N >> M) { // 注意 while 处理多个 case
        vec.clear();
        resVec.clear();
        for (int i = 0; i < N; i++) {
            country c;
            cin >> c.gold >> c.reward >> c.numOfPeoples;
			//使用下面这个才能过的原因应该是在检查点中由人数为0和奖牌数为0的输入数据
            //为了规避将除数为0的bug使用了下面这个方式
            c.goldScale = c.gold ? c.gold / c.numOfPeoples : 0 ;
            c.rewardScale =  c.reward ? c.reward / c.numOfPeoples : 0 ;
            vec.push_back(c);
        }
        for (int i = 0; i < M; i++) {
            cin >> id;
            resVec.push_back(vec[id]);
        }
        for (int i = 0; i < M; i++) {
            for (int j = 0; j < M; j++) {
                if (resVec[i].gold < resVec[j].gold)
                    resVec[i].rank[0] += 1;
                if (resVec[i].reward < resVec[j].reward)
                    resVec[i].rank[1] += 1;
                if (resVec[i].goldScale < resVec[j].goldScale)
                    resVec[i].rank[2] += 1;
                if (resVec[i].rewardScale < resVec[j].rewardScale)
                    resVec[i].rank[3] += 1;
            }
        }

        for (int i = 0; i < M; i++) {
            int min = 0;
            for (int j = 0; j < 4; j++) {
                if (resVec[i].rank[j] < resVec[i].rank[min])
                    min = j;
            }
            //排名:排名方式
            printf("%d:%d\n", resVec[i].rank[min] + 1, min + 1);

        }
        cout << endl;

    }
}

2.19多次查找

为了在规定的时间内多次查找数据,本次使用二分查找(使用递归形式的时间太久,这里使用循环方式的)

查找_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;
#define MAXSIZE 101`
bool binarySearch(int a[], int left, int right, int  num) {
    while(left<=right){
        int mid= (left+right)/2;
        if(a[mid]<num) left = mid+1;
        else if(a[mid]>num){
            right = mid-1;
        }
        else{
            return true;
        }
    }
    return false;

}
int main() {
    int a[101] = {0};
    int b[101] = {0};
    int n;
    while (cin >> n) { // 注意 while 处理多个 case
        int num, i, k;
        for (i = 0; i < n; i++) {
            cin >> a[i];
        }
        sort(a, a + n);
        cin >> num;
        for (i = 0; i < num; i++) {
            cin >> k;
            if (binarySearch(a, 0, n - 1, k)) {
                cout << "YES" << endl;
            } else cout << "NO" << endl;
        }

    }
}

2.20找最小数

找最小数_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;

struct  stu {
    int x, y;
};
bool compare(stu d1, stu d2) {
    if (d1.x == d2.x) {
        return d1.y < d2.y;
    }
    return d1.x < d2.x;
}

int main() {
    int n;
    vector<stu> vec;
    while (cin >> n) {
        vec.clear();
        for (int i = 0; i < n; i++) {
            stu d;
            cin >> d.x >> d.y;
            vec.push_back(d);
        }
        sort(vec.begin(), vec.end(), compare);
        cout << vec[0].x << " " << vec[0].y << endl;
    }
}

2.21 找位置

找位置_牛客题霸_牛客网 (nowcoder.com)

本题为寻找多个重复的元素出现的位置,下次再次遇到这种情况可以使用逐一比较的方法

#include <string>
#include <iostream>
using namespace std;
int main() {
    string str;
    while(cin>>str){
        for(int i=0;i<str.size();i++){
            if(str[i]=='*') continue;
            int tmp=i;
            for(int k=i+1;k<str.size();k++){
                if(str[i]==str[k]){
                    str[k]='*';//修改代表访问过
                    cout<<str[i]<<":"<<tmp<<",";
                    tmp=k;
                }
            }
            //重复
            if(tmp!=i){
                cout<<str[i]<<":"<<tmp<<endl;
            }
        }
    }
}

3.字符串习题

*字符串的一些用法

s

3.1 特殊乘法

本题中需要注意的一点是,怎么将字符9转换成整数9!!!!

特殊乘法_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<string>

using namespace std;

int main() {
    string a,b;
    while (cin >> a >> b) { // 注意 while 处理多个 case
        int num=0;
        for(int i=0;i<a.size();i++){

            for(int j=0;j<b.size();j++){

                num+=(a[i]-'0')*(b[j]-'0');
            }
        }
        cout<<num<<endl;
    }

}

3.2字符转换

密码翻译_牛客题霸_牛客网 (nowcoder.com)

本题重点:如何获取一整行的字符串输入,和判断字符是否是字母

#include <iostream>
#include<string>
using namespace std;

int main() {
    // int a, b;
    string a;
    while (getline(cin,a)) { // 注意 while 处理多个 case
        for(int i=0;i<a.size();i++){

            if((a[i]>='a'&&a[i]<='z')||(a[i]>='A'&&a[i]<='Z')){

                if(a[i]=='z')
                    a[i]='a';
                else if(a[i]=='Z')
                    a[i]='A';
                else{
                      a[i]+=1;
                               }
            }
        }
        cout<<a<<endl;
    }
}

3.3 密码转换

简单密码_牛客题霸_牛客网 (nowcoder.com)

本题主要是看穿规律,然后利用取余规律来进行转换

#include <iostream>
#include <string>
using namespace std;

int main() {
    string str;
    while (getline(cin,str)) { // 注意 while 处理多个 case
        if(str=="ENDOFINPUT"){
            break;
        }
        getline(cin,str);//密文
        for(int i=0;i<str.size();i++){
            if(str[i]>='A'&&str[i]<='Z'){
            str[i] =((str[i]-'A'-5+26)%26) +'A';//将数字转换成字母表中循环向前移动五位
            }
        }
        cout<<str<<endl;
        getline(cin,str);
        
    }
}

3.4 计算字符出现次数

本题注意一个函数memset初始化数组的函数(头文件为#include)

统计字符_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<string>
#include<cstring>//memset的头文件
#include<cstdio>
using namespace std;
#define MAXIZE 1000
int main() {
    string a;
    string str;
    int nums[MAXIZE]={0};
    while (getline(cin,a)) { 
        // 注意 while 处理多个   
        if(a=="#") break;
        memset(nums,0,sizeof (nums));//初始化整个数组
        
        getline(cin,str);
        for(int j=0;j<str.size();j++){
            nums[str[j]]++;
        }
        for(int i=0;i<a.size();i++){

            cout<<a[i]<<" "<<nums[a[i]]<<endl;
        }
    }
}

3.5 统计大写字母出现次数

本题依然是利用字母对应数组序号的思想

字母统计_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<string>
#include<cstring>
using namespace std;

int main() {
    string a;
    int nums[26];
    while (getline(cin, a)) { // 注意 while 处理多个 case
        memset(nums, 0, sizeof (nums));
        for (int i = 0; i < a.size(); i++) {
            if (a[i] >= 'A' && a[i] <= 'Z') {
                nums[a[i] - 'A']++;
            }
        }
        char ch = 'A';
        for (int i = 0; i < 26; i++) {
           
            cout << ch << ":" << nums[i] << endl;
             ch ++;
        }

    }
}

3.6 SKEW数

本题为傻瓜题照着题目说的写即可。

skew数_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<string>
#include<math.h>
using namespace std;

int main() {
    string str;
    int x, k;
    while (cin >> str) { // 注意 while 处理多个 case
        int res = 0;
        for (int i = 0; i < str.size(); i++) {
            x = str[i] - '0';
            k = str.size() - i;
            res += (str[i] - '0') * (pow(2, k) - 1);
        }
        cout << res << endl;
    }
}

3.7 查找字符串

单词替换_牛客题霸_牛客网 (nowcoder.com)

本题主要是使用了string的find,erase,insert各种操作

#include <iostream>
#include <string>
using namespace std;

int main() {
    string s, a, b;
    getline(cin, s);
    getline(cin, a);
    getline(cin, b);
    s = " " + s + " ";
    a = " " + a + " ";
    b = " " + b + " ";
    int start;
    while (1) {
        start = s.find(a);
        if (start == string::npos)
            break;
        else {
            //本题主要是字符串的综合应用
            s.erase(start, a.length());
            s.insert(start, b);
        }
    }
    int n = s.size();
    cout << s.substr(1, n - 2);
    return 0;
}

3.8 将单词首字母转换成大写

本题按照题意来写即可,注意怎么小写转换成大写

首字母大写_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<string>

using namespace std;

int main() {
    string str;
    while(getline(cin,str)){
        char ch ='a';
        for(int i=0;i<str.size();i++){
            if(str[i]>='a'&&str[i]<='z')
          if(i==0||str[i-1]==' '||str[i-1]=='\t'||str[i-1]=='\r'||str[i-1]=='\n')
                str[i]=(str[i]-'a')+'A';
        }
        cout<<str<<endl;
    }
}

3.9 浮点数加法

浮点数加法_牛客题霸_牛客网 (nowcoder.com)

这里先将两个字符串补齐,再利用进位机制来处理即可。

//这里我先将两个字符串小数点前后补齐到相同的长度,再一一对位相加 (这里记得进位
#include <iostream>
#include<string>
using namespace std;

int main() {
    string a,b;
    string longer,shorter;
    while (getline(cin,a)) { // 注意 while 处理多个 case
        getline(cin,b);

        int find1=a.find('.');
        int find2 = b.find('.');//小数点位置
        if(find1<find2){
            longer = b;
            shorter =a;
        }
        else{
            longer =a;
            shorter = b;
        }//为了方便最高一位进位,在最高位前添加一位
        longer.insert(0,"0");
       do{
           //补全小数点前的0
            shorter.insert(0,"0");
            find1=longer.find('.');
            find2 = shorter.find('.');
        } while(find1!=find2);

        if(longer.size()<shorter.size()){
            swap(longer,shorter);
        }
        while(longer.size()!=shorter.size()){
            shorter.insert(shorter.size(),"0");
		  //补全小数点后的0
        }

        int flag=0;
        for(int i=longer.size()-1;i>=0;i--){
            if(longer[i]=='.') continue;
            int res =(longer[i]-'0')+(shorter[i]-'0')+flag;
            flag=res/10;
            res%=10;
            longer[i]=res+'0';
        }
        if(flag!=0){
            longer[0]=flag+'0';
            cout<<longer;

        }
        else{//没有进位的话直接输出
            cout<<longer.substr(1,longer.size());
        }
    }
}

3.10 使用KMP求字符串完全匹配次数

#include <iostream>
#include<string>
using namespace std;
const int MAXM =1000;
int nextTable[MAXM];
void GetNextTable(string pattern){
    int m = pattern.size();
    int j=0;
    nextTable[j]=-1;
    int i=nextTable[j];
    for(j=0;j<m;j++){
        if(i==-1||pattern[i]==pattern[j]){
            i++;
            j++;
            nextTable[j]=i;
        }
        else{
            i=nextTable[i];
        }

    }
    return;
}

int KMP(string text, string pattern){
   GetNextTable(pattern);
   int n = text.size();
   int m = pattern.size();
   int number =0;
   int i,j;
   i=j=0;
   while(i<n){
       if(j==-1||text[i]==pattern[j]){
           i++;
           j++;
       }
       else{
           j=nextTable[j];
       }
       if(j==m){
           number++;
           j=nextTable[j];
       }
   }
   return number;
}
int main() {
    string str1 ="hello world";
    string str2="l";
    cout<<KMP(str1, str2);

}

4.特殊的数学问题

4.1十进制转二进制

二进制数_牛客题霸_牛客网 (nowcoder.com)

本题的重点是如何将十进制数转换成二进制数,使用栈的特性便可以轻松解决。

#include <iostream>
#include<stack>
using namespace std;
int main() {
    int a;
    stack<int> s;
    while(cin>>a){
        while(a!=0){
            s.push(a%2);
            a/=2;
        }
        while(!s.empty()){
            cout<<s.top();
            s.pop();
        }
        cout<<endl;
    }
}

4.2 使用大数除法的十进制转二进制

本题的数字过长所以必须使用字符串来完成大数除法

进制转换_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<stack>
#include<string>
using namespace std;

string Divide(string str, int x) {
    int remainder = 0;
    for (int i = 0; i < str.size(); i++) {
        int current = remainder * 10 + str[i] - '0';
        str[i] = current / x + '0';
        remainder = current % x;
    }
    int pos = 0;
    while (str[pos] == '0')
        pos++;
    return str.substr(pos);
}

int main() {
    string str;
    stack<int> s;
    while (cin >> str) {
        while (str.size() != 0) {
            int last = str[str.size() - 1] + '0';
            s.push(last %= 2);
            str = Divide(str, 2);
        }
        while (!s.empty()) {
            cout << s.top();
            s.pop();
        }
        cout << endl;
    }
}

4.3 二进制转十进制

这里涉及到了大数的加法和乘法,这里我们需要用字符串来一一实现

进制转换_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<vector>
#include<string>
#include<math.h>
using namespace std;

string Divide(string str, int x) {
    int remainder = 0;
    for (int i = 0; i < str.size(); i++) {
        int current = remainder * 10 + str[i] - '0';
        str[i] = current / x + '0';
        remainder = current % x;
    }
    int pos = 0;
    while (str[pos] == '0')
        pos++;
    return str.substr(pos);
}
string Multiple(string str, int x){
    int carry = 0;
    for(int i=str.size()-1;i>=0;i--){
        int current = x*(str[i]-'0')+carry;
        str[i] = current%10+'0';
        carry = current/10;
    }
    if(carry!=0){
        str="1"+str;
    }
    return str;

}
string Add(string str, int x){
    int carry=x;
    for(int i=str.size()-1;i>=0;i--){
        int current =(str[i]-'0')+carry;
        str[i] = current%10+'0';
        carry = current/10;
    }
    if(carry!=0){
        str = "1"+str;
    }
    return str;
}
int main() {
    string str;
    vector<int> s;
    while (cin >> str) {
        long long res = 0;
        while (str.size() != 0) {
            int last = str[str.size() - 1] + '0';
            s.push_back(last % 2);
            str = Divide(str, 2);
        }
        int flag = 0;
        string answer="0";
        for(int i=0;i<s.size();i++) {

            answer = Multiple(answer,2);
            answer = Add(answer,s[i]);

        }
        cout << answer << endl;
    }
}

4.4 M进制转换成N进制

本题主要是 注意可能的进制用字母表示

#include <iostream>
#include <stack>
#include<string>
using namespace std;

int charToInt(char ch){
    if(ch>='0'&&ch<='9'){
        return ch-'0';
    }
    else{
        return ch-'A'+10;
    }
}
char intToChar(int n){
    if(n<=9) return n+'0';
    else return n-10+'a';
}
int main() {
    int a, b;
    string str;
    stack<char> s;
    while (cin >> a >> b) { // 注意 while 处理多个 case
        cin>>str;
        long long ans =0;//这里记得使用long long数据类型
        for(int i=0;i<str.size();i++){
            //转换成 十进制
            ans = ans*a+charToInt(str[i]);
        }
        if(ans ==0) cout<<ans<<endl;
        while(ans!=0){
            int num = ans%b;
            s.push(intToChar(num));
            ans/=b;
        }
         while (!s.empty()) {
            cout << s.top();
            s.pop();
        }
        cout << endl;
    }
}

4.5 十进制转八进制

八进制_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<stack>
using namespace std;
int main() {
    int a;
    stack<int> s;
    while(cin>>a){
        while(a!=0){
            s.push(a%8);
            a/=8;
        }
        while(!s.empty()){
            cout<<s.top();
            s.pop();
        }
        cout<<endl;
    }
}

4.6 A+B 转m进制

又一版 A+B_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<stack>
using namespace std;
int main() {
    long long a,b,m;//使用长整型防止超过表示范围
    stack<int> s;
    while (cin >>m) {
        if(m==0) break;
        cin>> a>>b;
        a+=b;
        if(a==0)
        cout<<0;
        while (a != 0) {
            s.push(a % m);
            a /= m;
        }
        while (!s.empty()) {
            cout << s.top();
            s.pop();
        }
        cout << endl;
    }
}

4.7 十六进制转十进制

进制转换_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include <string>
using namespace std;
int charToInt(char ch){
    if(ch>='0'&&ch<='9')
     return ch-'0';
     else{
        return ch-'A'+10;
     }
}
int main() {
    string str;
    long long ans =0;
    while(cin>>str){
        ans=0;
        str.erase(str.begin(), str.begin()+2);//删除开头的字符
        for(int i=0;i<str.size();i++){
            ans=ans*16+charToInt(str[i]);

        }
        cout<<ans<<endl;
    }
}

4.8 数制转换

数制转换_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include <stack>
#include<string>
using namespace std;

int charToInt(char ch) {
    if (ch >= '0' && ch <= '9') {
        return ch - '0';
    } else {
        if(ch>='A'&&ch<='Z')
            return ch - 'A' + 10;
        else
            return ch-'a'+10;
    }
}
char intToChar(int n) {
    if (n <= 9) return n + '0';
    else return n - 10 + 'A';
}
int main() {
    int a, b;
    string str;
    stack<char> s;
    while (cin >> a >>str>> b) { // 注意 while 处理多个 case
        long long ans = 0; //这里记得使用long long数据类型
        for (int i = 0; i < str.size(); i++) {
            //转换成 十进制
            ans = ans * a + charToInt(str[i]);
        }
        if (ans == 0) cout << ans << endl;
        while (ans != 0) {
            int num = ans % b;
            s.push(intToChar(num));
            ans /= b;
        }
        while (!s.empty()) {
            cout << s.top();
            s.pop();
        }
        cout << endl;
    }
}

4.9 最大公约数

最大公约数_牛客题霸_牛客网 (nowcoder.com)

本题利用一个特殊的公式求最大公约数

#include <iostream>
using namespace std;
//求最大公约数
int gcd(int a, int b){
    if(b==0) return a;
    else{
        return gcd(b,a%b);
    }
}
int main() {
    int a, b;
    while (cin >> a >> b) { // 注意 while 处理多个 case
        cout << gcd(a,b)<< endl;
    }
}

4.10 最小公倍数

a,b的最小公倍数是a和b的乘积除以最大公约数。

#include <iostream>
using namespace std;
//求最大公约数
int gcd(int a, int b){
    if(b==0) return a;
    else{
        return gcd(b,a%b);
    }
}
//求最小公倍数
int lcm(int a, int b){
    int n=gcd(a,b);
    return (a*b)/n;

}
int main() {
    int a, b;
    while (cin >> a >> b) { // 注意 while 处理多个 case
        cout << lcm(a,b)<< endl;
    }
}

4.11 判断最简真分数

最简真分数_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<vector>
using namespace std;
//求最大公约数
int gcd(int a, int b) {
    if (b == 0) return a;
    else {
        return gcd(b, a % b);
    }
}
//求最小公倍数
int lcm(int a, int b) {
    int n = gcd(a, b);
    return (a * b) / n;

}
int main() {
    int n;
    vector<int> vec;
    int num = 0;
    while (cin >> n) { // 注意 while 处理多个 case
        if (n == 0) break;
        vec.clear();
        num = 0;
        for (int i = 0; i < n; i++) {
            int a;
            cin >> a;
            vec.push_back(a);
        }
        for (int i = 0; i < vec.size() - 1; i++) {
            for (int j = i + 1; j < vec.size(); j++) {
                if (gcd(vec[i], vec[j]) == 1)
                    num += 1;
            }
        }
        cout << num << endl;
    }
}

4.12 判断是否是素数

素数判定_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<cmath>
using namespace std;

bool  judge(int n){
    //0,1,负数都是非素数
    if(n<=1) return false;
    int b = sqrt(n);
    for(int i=2;i<=b;i++){
        if(n%i==0) return false;
    }
    return true;
}

int main() {
    int a;
    while (cin >> a ) { // 注意 while 处理多个 case
        if(judge(a)){
            cout<<"yes"<<endl;
        }
        else cout<<"no"<<endl;
    }
}

4.13 输出个位数为1的素数

素数_牛客题霸_牛客网 (nowcoder.com)

本题有一个很重要的技巧,非素数一定存在一个素数作为他的因子

#include <iostream>
#include<cmath>
#include<vector>
#include<cstring>
using namespace std;
#define MAXN 1000000
bool isPrime[MAXN];
vector<int> prime;
bool  judge(int n){
    if(n==1) return true;
    int b = sqrt(n);
    for(int i=2;i<=b;i++){
        if(n%i==0) return false;
    }
    return true;
}
void init(){
    memset(isPrime,true,sizeof (isPrime));
    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+=i){
            isPrime[j]=false;
        }
    }
    return;
}

int main() {
    int a;
    init();

    while (cin >> a ) { // 注意 while 处理多个 case
        int i=0;
        int flag=0;
        while(prime[i]<=a){
            if(prime[i]%10==1){
                if(flag) cout<<" ";
                cout<<prime[i];
                flag=1;

            }
            i++;
        }
    }
}

4.14 质因数

质因数的个数_牛客题霸_牛客网 (nowcoder.com)

#include<iostream>
#include<cmath>
using namespace std;

int main(){
    int num;
    while(cin >> num){
        int cnt = 0;
        for(int i = 2; i <= sqrt(num); i ++){
            while(num % i == 0){
                cnt ++;
                num /= i;
            }
            if(num <= 1) break;
        }
        // 存在大于 sqrt(num) 的因子
        if(num > 1) cnt ++;
        cout << cnt;
    }
    return 0;
}

4.15 约数的个数

约数的个数_牛客题霸_牛客网 (nowcoder.com)

#include<iostream>
#include<cmath>
#include<vector>
using namespace std;


int main() {
    int num;
    vector<long long>  vec;
    while (cin >> num) {
        for (int i = 0; i < num; i++) {
            long long a;
            cin >> a;
            vec.push_back(a);
        }
        int cnt = 0;
        for (int j = 0; j < num; j++) {
            if (vec[j] != 1) cnt = 2;
            else cnt = 1;
            int bound =  sqrt(vec[j]);
            for (int i = 2; i <= bound; i ++) {
                if (vec[j] % i == 0) {
                    if (vec[j] == (i * i)) cnt += 1;
                    else cnt += 2;
                }

            }

            cout << cnt << endl;

        }
    }
    return 0;
}

4.16 整除问题

整除问题_牛客题霸_牛客网 (nowcoder.com)

#include<iostream>
#include<vector>

using namespace std;
//统计 num 中的质因子数
void getPrime(vector<int>& factors, int num) {
    for (int i = 2; i * i <= num; i ++) {
        while (num % i == 0) {
            factors[i] ++;
            num /= i;
            if (num <= 1) return;
        }
    }
    if (num > 1) factors[num] ++;
}

int main() {
    int n, a;
    while (cin >> n >> a) {
        vector<int> factor_a(1000), factor_n(1000);
        getPrime(factor_a, a);
        for (int i = 2; i <= n; i ++)
            getPrime(factor_n, i);
        int k = 1000;
        for (int i = 2; i <= a; i ++) {
            if (factor_a[i]) k = min(k, factor_n[i] / factor_a[i]);
        }
        cout << k << endl;
    }
    return 0;
}

4.17 快速幂的应用

求root(N, k)_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<stack>
using namespace std;
long long fastMi(long long x, long long y, int k) {
    long long  answer = 1;
    while (y != 0) {
        if (y % 2 == 1) {
            answer =answer* x%(k-1);

        }
        y /= 2;
        x = x*x%(k-1);
    }
    return answer;
}


int main() {
    // int a, b;
    long long x, y, k;

    while (cin >> x >> y >> k) { // 注意 while 处理多个 case

        int res = fastMi(x, y,k);
        printf("%d",res?res:k-1);
    }
}

4.18 矩阵乘法

计算两个矩阵的乘积_牛客题霸_牛客网 (nowcoder.com)

本题需要注意矩阵乘法的步骤

#include <iostream>
#include<cstdio>
using namespace std;

struct Matrix {
    int matrix[3][3];
    int row, col;
    Matrix(int r, int c): row(r), col(c) {};
};

void printMatrix(Matrix m) {
    for (int i = 0; i < m.row; i++) {
        for (int j = 0; j < m.col; j++) {
            cout << m.matrix[i][j] << " ";
        }
        cout << endl;
    }
}

Matrix mulptileMatrix(Matrix a, Matrix b) {
    Matrix ans(a.row, b.col);
    for (int i = 0; i < ans.row; i++) {
        for (int j = 0; j < ans.col; j++) {
            ans.matrix[i][j] = 0;
            for (int k = 0; k < a.col; k++) {
                ans.matrix[i][j] += a.matrix[i][k] * b.matrix[k][j];
            }
        }
    }
    return ans;
}
int main() {

    Matrix a(2, 3);
    Matrix b(3, 2);
    for (int i = 0; i < a.row; i++) {
        for (int j = 0; j < a.col; j++)
            cin >> a.matrix[i][j];

    }
    for (int i = 0; i < b.row; i++) {
        for (int j = 0; j < b.col; j++)
            cin >> b.matrix[i][j];

    }
    Matrix res = mulptileMatrix(a, b);
    printMatrix(res);

}

4.19 矩阵快速幂

矩阵幂_牛客题霸_牛客网 (nowcoder.com)

这里为了解决快速幂的问题,使用了一样的方法,记得掌握

#include <iostream>
#include<cstdio>
using namespace std;

struct Matrix {
    int matrix[10][10];
    int row, col;
    Matrix(int r, int c): row(r), col(c) {};
};

void printMatrix(Matrix m) {
    for (int i = 0; i < m.row; i++) {
        for (int j = 0; j < m.col; j++) {
            cout << m.matrix[i][j] << " ";
        }
        cout << endl;
    }
}

Matrix mulptileMatrix(Matrix a, Matrix b) {
    Matrix ans(a.row, b.col);
    for (int i = 0; i < ans.row; i++) {
        for (int j = 0; j < ans.col; j++) {
            ans.matrix[i][j] = 0;
            for (int k = 0; k < a.col; k++) {
                ans.matrix[i][j] += a.matrix[i][k] * b.matrix[k][j];
            }
        }
    }
    return ans;
}

Matrix fastMatrixMi(Matrix x, int k) {
    Matrix answer(x.row, x.col);
    for (int i = 0; i < answer.row; i++) {
        for (int j = 0; j < answer.col; j++) {
            if (i == j) {
                answer.matrix[i][j] = 1;
            } else {
                answer.matrix[i][j] = 0;
            }
        }
    }
    while (k != 0) {
        if (k % 2 == 1) {
            answer = mulptileMatrix(answer, x);
        }

        k /= 2;
        x = mulptileMatrix(x, x);
    }
    return answer;
}



int main() {

    int n, k;
    while (cin >> n >> k) {
        Matrix m(n, n);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                cin >> m.matrix[i][j];
            }
        }
        m = fastMatrixMi(m, k);
        printMatrix(m);
    }
}

4.20 矩阵加法

A+B for Matrices_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<cstdio>
using namespace std;

struct Matrix {
    int matrix[10][10];
    int row, col;
    Matrix(int r, int c): row(r), col(c) {};
};

void printMatrix(Matrix m) {
    for (int i = 0; i < m.row; i++) {
        for (int j = 0; j < m.col; j++) {
            cout << m.matrix[i][j] << " ";
        }
        cout << endl;
    }
}

Matrix mulptileMatrix(Matrix a, Matrix b) {
    Matrix ans(a.row, b.col);
    for (int i = 0; i < ans.row; i++) {
        for (int j = 0; j < ans.col; j++) {
            ans.matrix[i][j] = 0;
            for (int k = 0; k < a.col; k++) {
                ans.matrix[i][j] += a.matrix[i][k] * b.matrix[k][j];
            }
        }
    }
    return ans;
}

Matrix addMatrix(Matrix a, Matrix b) {
    Matrix ans(a.row, a.col);
    for (int i = 0; i < ans.row; i++) {
        for (int j = 0; j < ans.col; j++) {
            ans.matrix[i][j] = a.matrix[i][j] + b.matrix[i][j];
        }
    }
    return ans;

}

int solve(Matrix ans) {
    int num = 0;
    bool flag1 = 0;
    for (int i = 0; i < ans.row; i++) {
        for (int j = 0; j < ans.col; j++) {
            if (ans.matrix[i][j] == 0) {
                flag1 = true;
            } else {
                flag1 = false;
                break;
            }
        }
        if (flag1) num += 1;
    }
    flag1 = 0;
    for (int i = 0; i < ans.col; i++) {
        for (int j = 0; j < ans.row; j++) {
            if (ans.matrix[j][i] == 0) {
                flag1 = true;
            } else {
                flag1 = false;
                break;
            }
        }
        if (flag1) num += 1;
    }
    return num;
}
int main() {

    int n, k;
    while (cin >> n) {
        if (n == 0) break;
        cin >> k;
        Matrix a(n, k);
        Matrix  b(n, k);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < k; j++) {
                cin >> a.matrix[i][j];
            }
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < k; j++) {
                cin >> b.matrix[i][j];
            }
        }
        a = addMatrix(a, b);
        cout << solve(a) << endl;
    }
}

5.贪心算法

5.1匹配服务器

代理服务器_牛客题霸_牛客网 (nowcoder.com)

#include<iostream>
#include<vector>
#include<map>

using namespace std;

int getCnt(vector<string>& proxy, vector<string>& server, int m) {
    int  index=0;
    int count=0;
    while(index<m){
        int maxm=0;
        for(string ip:proxy){
            int j;
            for(j=index;j<m&&ip!=server[j];j++){}
            maxm=max(maxm, j-index);
        }
        if(maxm==0) return -1;
        index+=maxm;
        count++;
    }
    return count-1;
}
int main() {
    int n, m;
    while (cin >> n) {
        vector<string> proxy(n);
        for (int i = 0; i < n; i ++) {
            cin >> proxy[i];
        }
        cin >> m;
        vector<string> server(m);
        for (int i = 0; i < m; i ++)
            cin >> server[i];
        cout << getCnt(proxy, server, m);
    }
}

5.2 区间贪心:看电视节目

#include<iostream>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;

struct tv{
    int start;
    int end;
};

bool compare(tv a, tv b){
    return a.end<b.end;
}

int main() {
    int n;
    vector<tv> dianshi;
    while (cin >> n) {
        for(int i=0;i<n;i++){
            tv t;
            cin>>t.start>>t.end;
            dianshi.push_back(t);
        }
        sort(dianshi.begin(), dianshi.end(),compare);
        int timeNow=0;
        int num=0;
        for(int i=0;i<dianshi.size();i++){
            if(timeNow<=dianshi[i].start){
                timeNow=dianshi[i].end;
                num++;
            }
        }
        cout<<num<<endl;
    }
}

5.3 油价

To Fill or Not to Fill_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include <cstdio>
#include <algorithm>
/*
50 1300 12 8
6.00 1250
7.00 600
7.00 150
7.10 0
7.20 200
7.50 400
7.30 1000
6.85 300
50 1300 12 2
7.10 0
7.00 600

749.17
The maximum travel distance = 1200.00
*/
using namespace std;
/*
输入 : 
对于每种情况,第一行包含4个正数:Cmax(<=100),即油箱的最大容量;D(<=30000),
即杭州到目的地城市的距离;Davg(<=20),即汽车每单位汽油可行驶的平均距离;N(<=500),
即加油站总数。接下来是N行,每行包含一对非负数:Pi,煤气单价,Di(<=D),这个站到杭州的距离,i=1,…N。一行中的所有数字用空格隔开。

输出 :
对于每个测试用例,一行打印最便宜的价格,精确到小数点后2位。
假设开始时油箱是空的。如果无法到达目的地,请打印“最大行驶距离=X”,
其中X是车辆可以行驶的最大可能距离,精确到小数点后2位。 
*/
struct GasStation {
    double price;
    int distance;
};

bool ComparePrice(GasStation x, GasStation y) {
    return x.price < y.price;
}

int main() {
    int cmax, d, davg, n; // cmax : 箱的最大容量, d : 州到目的地城市的距离, davg : 车每单位汽油可行驶的平均距离, n : 加油站总数;
    while (cin >> cmax >> d >> davg >> n) {
        double currentprice = 0; // 当前油费 

        bool tag[d + 1]; // 记录当前有哪段道路是从加油站出发能走的 
        GasStation gasStation[n];

        for (int i = 1; i <= d; ++i) tag[i] = false;
        for (int i = 0; i < n; ++i) cin >> gasStation[i].price >> gasStation[i].distance;

        sort(gasStation, gasStation + n, ComparePrice); // 对油价按升序排 

        for (int i = 0; i < n; ++i) {  // 对tag[]进行记录, 并同时计算出 currentprice
            int currentdistance = 0; // 记录从这个加油站出发要用其油的距离 
            for (int j = gasStation[i].distance + 1; j <= gasStation[i].distance + cmax * davg; ++j) {
                if (tag[j] == false) { // 如果 tag[j]为假则可走 
                    tag[j] = true;
                    currentdistance++;
                }
                if (j == d || j == gasStation[i].distance + cmax * davg) { // 走到了尽头 
                    currentprice += gasStation[i].price  * currentdistance / (davg * 1.0);
                    break;
                }
            }
        }

        int fill = 1; // tag[]是否全为真的标志位
        double journey = 0;
        for (int i = 1; i <= d; ++i) {
            if (tag[i] == true) journey++;
            else {
                fill = 0;
                break;
            }
        }

        if (fill) printf("%.2f\n",currentprice);
        else printf("The maximum travel distance = %.2f\n", journey);    
    }
    return 0;
}

6.递归与分治

6.1 n的阶乘

n的阶乘_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
using namespace std;

long long factor(long long n){
    if(n==1||n==0)  return 1;
    else return n*factor(n-1);
}
int main() {
    int a;
    while (cin >> a) { // 注意 while 处理多个 case
        cout << factor(a)<< endl;
    }
}
// 64 位输出请用 printf("%lld")

6.2 杨辉三角

杨辉三角_牛客笔试题_牛客网 (nowcoder.com)

#include<iostream>
using namespace std;
void solve(int n){
    int Matrix[n][n];
    for(int i=0;i<n;i++){
        for(int j=0;j<=i;j++){
            if(j==0||j==i)
                Matrix[i][j]=1;

            else{
                Matrix[i][j]= Matrix[i-1][j-1]+Matrix[i-1][j];
            }
            printf("%5d",Matrix[i][j]);
        }
        cout<<endl;
    }

}
int main(){
    int a;
    while(cin>>a){
     solve(a);
    }
}

6.3 全排列(元素个数与之前一样)

全排列_牛客题霸_牛客网 (nowcoder.com)

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
string a;


int main()
{
    vector<char> vec;
    char num[6];
    while(cin>>a){
        int n=a.size();
        for(int i=0;i<n;i++){
            num[i]=a[i];

        }
        //while(next_permutation(num,num+n));
        do{
            cout<<num<<endl;
        }while(next_permutation(num, num+n));
    }

}

6.4 斐波那契数列

Fibonacci_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
using namespace std;

int solve(int n){
    if(n==0) return 0;
    if(n==1||n==2) return 1;
    else return solve(n-1)+solve(n-2);
}

int main() {
    int a;
    while (cin >> a ) { // 注意 while 处理多个 case
        cout << solve(a)<< endl;
    }
}
// 64 位输出请用 printf("%lld")

6.5 求完全二叉树结点的子树

二叉树_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
using namespace std;
int a;
int solve(int m){
    if(m>a) return 0;

    //左子树和右子树
    else return solve(2*m)+solve(2*m+1)+1;
}

int main() {
    int  b;
    while (cin >> b>> a) { // 注意 while 处理多个 case
        if(a==0) break;
        cout<<solve(b)<<endl;
    }
}
// 64 位输出请用 printf("%lld")

6.6分解数字转二的次幂

2的幂次方_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<vector>
using namespace std;

void solve(int n) {
    if (n == 1) //这里的 1代表2的1次幂
        cout << "2";
    else if (n == 2) //2代表2的2次幂
        cout << "2(2)";
    else if (n == 0)
        cout << "2(0)";
    else {
        vector<int> vec;
        while (n != 0) {
            vec.push_back(n % 2);
            n /= 2;
        }
        vector<int> res;
        for (int i = vec.size() - 1; i >= 0; i--)
            if (vec[i] == 1) res.push_back(i);

        for (int i = 0; i < res.size(); i++) {
            if (res[i] > 2) {
                cout << "2(";
                solve(res[i]);
                cout << ")";
                if (i != res.size() - 1) {
                    cout << "+";
                }
            } else {
                solve(res[i]);
                if (i != res.size() - 1) {
                    cout << "+";
                }
            }
        }

    }
}

int main() {
    int a;
    while (cin >> a) {
        solve(a);
    }

}

7.搜索算法

7.1 广度优先算法

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int MAXN=10001;
struct status{
    int n,t;
    status(int n, int t):n(n),t(t){};
};

bool visit[MAXN];






int bfs(int n, int k){
    queue<status>myQueue;
   myQueue.push(status(n,0));//初始状态入队
    visit[n]=true;
    while(!myQueue.empty()){
        status current = myQueue.front();
        myQueue.pop();
        if(current.n==k){
            return current.t;
        }
        else{

            for(int i=0;i<3;i++){
                 status next(current.n, current.t+1);
                if(i==0)next.n+=1;
                else if(i==1)next.n-=1;
                else if(i=2)next.n*=2;
                if(next.n<0||next.n>=MAXN||visit[next.n]){
                    continue;
                }
                if(next.n<0||next.n>10001||visit[next.n])continue;//越界或者已被访问
                myQueue.push(next);
                visit[next.n]=true;

            }
        }
    }
}

int main(){
    int n,k;


        memset(visit,false,sizeof (visit));
        cout<<bfs(5,17)<<endl;
}

7.2 广度优先解决玛雅密码问题

玛雅人的密码_牛客题霸_牛客网 (nowcoder.com)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<map>
using namespace std;
const int MAXN = 10001;

struct data1 {
    string str;
    int depth;
    data1(string str, int depth): str(str), depth(depth) {};
};

void solve(string str) {
    map<string, int> m;
    queue<data1> myQueue;
    myQueue.push(data1(str, 0));
    while (!myQueue.empty()) {
        data1 current = myQueue.front();
        myQueue.pop();
        if (current.str.find("2012") != string::npos) {
            cout << current.depth << endl;
            return;
        }
        for (int i = 1; i < str.size() - 1; i++) {
            for (int j = 0; j < 2; j++) {
                string str = current.str;

                if (j == 0) {
                    swap(str[i], str[i - 1]);

                } else {
                    swap(str[i], str[i + 1]);
                }
                //将已经访问过的字符串记录状态不在访问
                //节省内存
                if (m[str] == 1) continue;
                else m[str] = 1;
                myQueue.push(data1(str, current.depth + 1));
            }

        }
    }
}
int main() {
    int n;
    string str;
    while (cin >> n) {
        cin >> str;
        solve(str);
    }
}

7.3 深度优先算法搜索状态问题

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<map>
#include<algorithm>
using namespace std;
const int MAXN=25;
int side,m;
int sticks[MAXN];
int visit[MAXN];
bool DFS(int sum, int number, int position){
    if(number==3) return true;
    int sample=0;
    for(int i=position;i<m;i++){
        if(visit[i]||sum+sticks[i]>side||sticks[i]==sample){
            continue;
        }
        visit[i]=true;
        if(sum+sticks[i]==side){
            if(DFS(0,number+1,0)){
                return true;
            }
            else{
                sample=sticks[i];
            }

        }
        else{
            if(DFS(sum+sticks[i],number,i+1)){
                return true;
            }
            else{
                sample = sticks[i];
            }
        }
        visit[i]=false;
    }
    return false;
}

bool compare(int x, int y){
    return x>y;
}

int main(){
    cin>>m;
    memset(sticks,0,sizeof (sticks));
    int length=0;
    for(int i=0;i<m;i++){
        cin>>sticks[i];
        length+=sticks[i];
    }
    if(length%4!=0){
        cout<<"no"<<endl;
    }
    else{
        sort(sticks,sticks+m,compare);

        side = length/4;
        if(sticks[0]>side){
            cout<<"no";
        }
        else if(DFS(0,0,0)){
            cout<<"yes"<<endl;
        }
        else cout<<"no";
    }
}

7.4 神奇的口袋

神奇的口袋_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 21
int weight[maxn];
int n;

int visit[maxn];
int num=0;
void dfs(int sum, int k) {
  
    for (int i = k; i < n; i++) {
        int cal =sum+weight[i];
        if (cal> 40) {
            dfs(sum,i+1);
        }
        
        else if(cal<40){
           dfs(cal,i+1);
            }
        else{
            num++;
        }
    }
}

int main() {
    while (cin >> n) {
        memset(weight, 0, sizeof(weight));
        // 注意 while 处理多个 case
        for (int i = 0; i < n; i++) {
            cin >> weight[i];
        }
        sort(weight, weight + n);
        if (weight[0] > 40) {
            cout << 0 << endl;
        } else {
            dfs(0,0);
            cout<<num;
        }

    }
}

7.4 八皇后问题

这里注意不能处于同一斜行的条件

八皇后_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int> vec;
int visit[9];
int arr[9];
bool judge(int k, int a){
    for(int i=1;i<k;i++){
        if(arr[i]==a||(i-arr[i]==k-a)||(i+arr[i]==a+k)){
            return false;
        }
    }
    return true;
}


void dfs(int k,int n){
    if(k==9){
        vec.push_back(n);
        return;

    }
    for(int i=1;i<9;i++){

        if(judge(k,i)){
            arr[k]=i;
           dfs(k+1, n*10+i);
        }
    }

}



int main() {
    dfs(1,0);
    sort(vec.begin(),vec.end());
    int n;
    while(cin>>n){
        cout<<vec[n-1]<<endl;
    }
}
// 64 位输出请用 printf("%lld")

8.动态规划

8.1 上楼梯

N阶楼梯上楼问题_牛客题霸_牛客网 (nowcoder.com)

#include <cstring>
#include <iostream>
using namespace std;
const int maxn=91;
int floor[maxn];
int fib(int n){
     int answer;
    if(n==0||n==1)
        answer=n;
     
    else if(floor[n]!=-1){
       answer= floor[n];
    }
    else{
        answer = fib(n-1)+fib(n-2);
        
    }
    floor[n]=answer;
    return answer;
}

int main() {
    int n;
    while (cin >> n) { // 注意 while 处理多个 case
        memset(floor, -1, sizeof(floor));
        cout<<fib(n+1)<<endl;
    }
}
// 64 位输出请用 printf("%lld")

8.2 吃糖果

吃糖果_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
using namespace std;
const int maxn=21;
int solve(int n){
    int cho[maxn]={0};
    cho[0]=1;
    cho[1]=1;
    for(int  i=2;i<=n;i++){
        cho[i]=cho[i-1]+cho[i-2];
    }
    return cho[n];
}
int main() {
    int n;
    while (cin >> n) { // 注意 while 处理多个 case
        // cout << a + b << endl;
        cout<<solve(n)<<endl;
    }
}

8.3 最长子序列和

超时方案(递归效率太低了):

最大序列和_牛客题霸_牛客网 (nowcoder.com)

#include <cstring>
#include <iostream>
using namespace std;
const int maxn = 1e6 + 10;
//const int INF = INT_MAX; //int数据的最大值,即无穷大
long long arr[maxn];
long long  Fun1(int n) {
    long long answer;
    if (n == 0) answer = arr[n];
    else {
        answer = max(arr[n], Fun1(n - 1) + arr[n]);
    }
    return answer;

}
int main() {
    int n;
    while (cin >> n) { // 注意 while 处理多个 case
        for (int i = 0; i < n; i++) {
            cin >> arr[i];
        }
        long long res = Fun1(0); //
        for (int i = 1; i < n; i++) {
           res=max(res,Fun1(i));
        }
        cout << res << endl;
    }
}
// 64 位输出请用 printf("%lld")

不会超时的动态规划方法:

#include <cstring>
#include <iostream>
using namespace std;
const int maxn = 1e6 + 10;
//const int INF = INT_MAX; //int数据的最大值,即无穷大
long long arr[maxn];
long long memo[maxn];
void Fun2(int n){
    long long answer;
    for(int i=0;i<n;i++){
   if (i == 0) answer = arr[i];
    else {
        answer = max(arr[i], memo[i-1]+ arr[i]);
    }
    memo[i]=answer;

    }
}
int main() {
    int n;   
    while (cin >> n) { // 注意 while 处理多个 case
         memset(memo, -1, sizeof(memo));
        for (int i = 0; i < n; i++) {
            cin >> arr[i];
        }
       Fun2(n);
       long long res = memo[0];
        for (int i = 1; i < n; i++) {
            res = max(res, memo[i]);
        }
        cout << res << endl;
    }
}

8.4 最长递增子序列

最大子矩阵__牛客网 (nowcoder.com)

#include <cstring>
#include <iostream>
#include<climits>
using namespace std;
const int maxn=100;
const int inf =INT_MAX;
int arr[maxn];
int memo[maxn];
int total[maxn][maxn];

int fib(int n){
    int maxm=-inf;
    for(int i=0;i<n;i++){
        if(i==0) memo[i]=arr[i];
        else{
            memo[i]=max(arr[i],arr[i]+memo[i-1]);
        }
        maxm = max(maxm,memo[i]);
    }
    return maxm;
}

int solve(int n){
    int maxmal=-inf;
    for(int i=0;i<n;i++){
        for(int j=i;j<n;j++){
            for(int k=0;k<n;k++){
                if(i==0){
                    arr[k]=total[j][k];
                }
                else{
                    arr[k]= total[j][k]-total[i-1][k];
                }
            }
            int current = fib(n);
        maxmal = max(current, maxmal);
        }
        
    }
    return maxmal;
}

int main() {
    int n;
    int matrix[maxn][maxn];
    while(cin>>n){
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cin>>matrix[i][j];
        }
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(i==0){
                total[i][j]=matrix[i][j];
            }
            else{
                total[i][j]=total[i-1][j]+matrix[i][j];
            }

        }
    }
    cout<<solve(n)<<endl;
}

8.5 最大递增子序列2

最大连续子序列_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include <cstring>
#include <iostream>
#include<climits>
using namespace std;
const int maxn = 10001;
const int inf = INT_MAX;
int arr[maxn];
int memo[maxn];
int start[maxn];

void fib(int n) {
    int maxm = -inf;
    for (int i = 0; i < n; i++) {        
        if (i == 0) memo[i] = arr[i];
        else {
          //  memo[i] = max(arr[i], arr[i] + memo[i - 1]);
            if(arr[i]<arr[i]+memo[i-1]){
                start[i]=start[i-1];
                memo[i]=arr[i]+memo[i-1];
            }
            else{
                memo[i]=arr[i];
            }
        }

    }
}
int main() {
    int n;
    while (cin >> n) { // 注意 while 处理多个 case
        if(n==0) break;
        int flag=0;
        memset(memo,0,sizeof(memo));
        for(int i=0;i<n;i++){
            cin>>arr[i];
            if(arr[i]>=0) flag=1;
            start[i]=arr[i];//起始是自己
        }
        if(flag==0)  cout<<0<<" "<<arr[0]<<" "<<arr[n-1]<<endl;
    else{
        fib(n);
        int maxIndex=0;
        int max=memo[0];
        for(int i=0;i<n;i++){
            if(max<memo[i]){
                max=memo[i];
                maxIndex=i;
            }
        }
    
        cout<<max<<" "<<start[maxIndex]<<" "<<arr[maxIndex]<<endl;
    }
    }
}

8.6 最长不递增子序列

拦截导弹_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
using namespace std;
const int maxn=26;
int dp[maxn];
int arr[maxn];

int fun(int n){
    int answer=1;
    for(int i=0;i<n;i++){
        dp[i]=1;
        for(int j=0;j<i;j++){
            if(arr[j]>=arr[i]){
                dp[i]=max(dp[i],dp[j]+1);
            }
        }
        answer=max(answer,dp[i]);
    }
    return answer;
}
int main() {
    int n;
    while (cin >> n) { // 注意 while 处理多个 case
        // cout << a + b << endl;
        for(int i=0;i<n;i++){
            cin>>arr[i];
        }
        cout<<fun(n)<<endl;
    }
}

8.7 最大上升子序列和

最大上升子序列和_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
using namespace std;
const int maxn = 1001;
int dp[maxn];
int arr[maxn];

int fun(int n) {
    int answer = -maxn;
    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]);
    }
    return answer;
}
int main() {
    int n;
    while (cin >> n) { // 注意 while 处理多个 case
        // cout << a + b << endl;
        for (int i = 0; i < n; i++) {
            cin >> arr[i];
        }
        cout << fun(n) << endl;
    }
}

int main() {
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
        cin >>arr[i];
    }
    support[0]=-maxn;
    int length=0;
    for(int i=0;i<n;i++){
        if(support[length]<arr[i]){
            support[++length]=arr[i];
        }
        else{
            int pos  = lower_bound(support,support+length,arr[i])-support;
            support[pos]=arr[i];
        }
    }
    cout<<length;

}

8.8 合唱队形

合唱队形_牛客题霸_牛客网 (nowcoder.com)

两边小中间大的最大长度。

#include <iostream>
#include<algorithm>
using namespace std;
const int maxn = 101;
int dp[maxn];
int dp2[maxn];
int arr[maxn];

int fun(int n) {
    int answer = 1;
    for (int i = 0; i < n; i++) {
        dp[i] = 1;
        for (int j = 0; j < i; j++) {
            if (arr[j] < arr[i]) {
                dp[i] = max(dp[i], dp[j] + 1);
            }
        }
        answer = max(dp[i], answer);
    }
    return answer;
}

int fun2(int n) {
    int answer = 1;
    for (int i = n-1; i >=0; i--) {
        dp2[i] = 1;
        for (int j=n-1; j > i; j--) {
            if (arr[j] < arr[i]) {
                dp2[i] = max(dp2[i], dp2[j] + 1);
            }
        }
        answer = max(dp2[i], answer);
    }
    return answer;
}

int main() {
    int n;
    while (cin >> n) { // 注意 while 处理多个 case
        for (int i = 0; i < n; i++) {
            cin >> arr[i];
        }
        int  ans=1;
        fun(n);
        fun2(n);
        for(int i=0;i<n;i++){
            if(dp[i]+dp2[i]>ans){
                ans =dp[i]+dp2[i];
            }
        }
        cout << (n - ans+1) << endl;
    }
}

8.9 0-1背包问题,同一件物品最多只能选择一件

点菜问题_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<cstring>
using namespace std;
const int maxn=1001;
int weight[maxn];
int value[maxn];
int dp[maxn][maxn];
int main() {
    int c, n;
    while (cin >> c >> n) { // 注意 while 处理多个 case

        for(int i=1;i<=n;i++){
            cin>>weight[i]>>value[i];
        }
       for(int i=0;i<=n;i++){
        dp[i][0]=0;

       }
       for(int j=0;j<=c;j++){
           dp[0][j]=0;
       }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=c;j++)
            if(j<weight[i]){
                dp[i][j]=dp[i-1][j];
            }
            else{
                dp[i][j]=max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i]);
                //cout<<dp[i][j]<<endl;
            }
        }
        cout<<dp[n][c]<<endl;

    }
}

空间优化版本:

#include <iostream>
#include<cstring>
using namespace std;
const int maxn = 1001;
int weight[maxn];
int value[maxn];
int dp[maxn];
int main() {
    int c, n;
    while (cin >> c >> n) { // 注意 while 处理多个 case

        for (int i = 1; i <= n; i++) {
            cin >> weight[i] >> value[i];
        }
        memset(dp, 0, sizeof (dp));
        for (int i = 1; i <= n; i++) {
            for (int j = c; j >= weight[i]; j--) //逆向更新
                dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
            //cout<<dp[i][j]<<endl;

        }
        cout << dp[c] << endl;

    }
}
// 64 位输出请用 printf("%lld")

采药__牛客网 (nowcoder.com)

一个代码,换了种问法而已。

8.11 最小邮票数

最小邮票数_牛客题霸_牛客网 (nowcoder.com)

#include<iostream>
#include<algorithm>
#include<vector>

using namespace std;

const int MAX = 100000;

int main() {
    int m, n;
    while (cin >> m >> n) {
        vector<int> stamps(n + 1, 0);
        vector<int> dp(m + 1, MAX);
        for (int i = 1; i <= n; i ++)
            cin >> stamps[i];
        dp[0] = 0;
        for (int i = 1; i <= n; i ++) {
            for (int j = m; j >= stamps[i]; j --) {
                dp[j] = min(dp[j], dp[j - stamps[i]] + 1);

            }
        }

        if (dp[m] == MAX)
            cout << 0 << endl;
        else
            cout << dp[m] << endl;
    }
    return 0;
}

8.12 完全背包

每件物品无穷个,与0/1背包区分

#include<iostream>
#include<algorithm>
#include<vector>
#include<cstring>
using namespace std;

const int MAXN = 110;
const int MAXM=1e5+10;
int weight[MAXN];
int value[MAXN];
int dp[MAXN];
int main() {
    int m, n;
    while (cin >> n) {
        for(int i=1;i<=n;i++){
            cin>>value[i]>>weight[i];
        }
        cin>>m;
        memset(dp,0,sizeof (dp));
        for(int i=1;i<=n;i++){
            for(int j=weight[i];j<=m;j++){
                 dp[j]=max(dp[j],dp[j-weight[i]]+value[i]);//拿了一件还可以拿

            }
        }
        cout<<dp[m]<<endl;
    return 0;
}}

8.13 多重背包

每个商品的数量都是有限的

多重背包__牛客网 (nowcoder.com)

#include <iostream>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 1e4+10;
int weight[maxn];
int amount[maxn];
int value[maxn];
int dp[maxn];
int newWeight[20*maxn];
int newValue[20*maxn];
数量、体积和价值
int main() {
    int m, n;
    while(cin>>m>>n){
    for(int i=0;i<n;i++){
       cin>>amount[i]>>weight[i]>>value[i];
    }
    int num=0;
    for(int i=0;i<n;i++){
        for(int k=1;k<=amount[i];k*=2){
            newWeight[num]=weight[i]*k;
            newValue[num]=value[i]*k;
            num++;
            amount[i]-=k;
        }
        if(amount[i]>0){
            newWeight[num]=weight[i]*amount[i];
            newValue[num]=value[i]*amount[i];
            num++;

        }
    }
    memset(dp,0,sizeof (dp));
    for(int i=0;i<num;i++){
        for(int j=m;j>=newWeight[i];j--){
            dp[j]=max(dp[j],dp[j-newWeight[i]]+newValue[i]);
        }
    }

    cout<<dp[m]<<endl;
    }
}

8.14 三角形

三角形__牛客网 (nowcoder.com)

#include <iostream>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 1001;
class Solution {
public:
    int minimumTotal(vector<vector<int> > &triangle) {
        int res[maxn][maxn];
       
        int n=triangle.size();
        for (int i = 0; i < n; ++i) {
        for (int j = 0; j <= i; ++j) {
            vector<int> vec=triangle[i];
            res[i][j] = vec[j];//初始值设定
        }
    }
    for (int i = n - 2; i >= 0; --i) {//倒推回去
        for (int j = 0; j <= i; ++j) {//第i行只有i个元素
            //
            res[i][j] += min(res[i + 1][j], res[i + 1][j + 1]);
        }
    }
        return res[0][0];
        
    }
};

8.15 题解 | #Monkey Banana Problem#_牛客网 (nowcoder.com)

8.16 放苹果

放苹果__牛客网 (nowcoder.com)

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int main() {
	int M, N;
	while (cin >> M >> N) {
		if (M < 1 || M>10 || N < 1 || N>10) {
			cout << -1 << endl;
			continue;
		}
		vector<vector<int>> dp(M + 1, vector<int>(N + 1, 0));
		for (int i = 1; i <= N; i++) dp[0][i] = 1;
		for (int i = 1; i <= M; i++)
			for (int j = 1; j <= N; j++)
				dp[i][j] = dp[i][j - 1] + (i < j ? 0 : dp[i - j][j]);
		cout << dp[M][N] << endl;
	}
}

8.17 划分

整数拆分_牛客题霸_牛客网 (nowcoder.com)

真的太难想了。。。

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

9.二叉树

9.1 根据前序和中序生成二叉树序列

二叉树遍历_牛客题霸_牛客网 (nowcoder.com)

#include<iostream>
#include<algorithm>
#include<vector>
#include<cstring>
using namespace std;

struct treeNode {
    char data;
    treeNode* leftChild;
    treeNode* rightChild;
    treeNode(char c): data(c), leftChild(nullptr), rightChild(nullptr) {};
};

treeNode* Build(string pre, string in) {
    if (pre.size() == 0) return nullptr;
    char c = pre[0];
    treeNode* root = new treeNode(c);
    int pos = in.find(c);
    root->leftChild = Build(pre.substr(1, pos), in.substr(0, pos));
    root->rightChild = Build(pre.substr(pos + 1), in.substr(pos + 1));
    return root;
}

void postOrder(treeNode* root) {
    if (root == nullptr) return;
    postOrder(root->leftChild);
    postOrder(root->rightChild);
    cout << root->data;

}

int main() {
    string pre, in;
    while (cin >> pre >> in) {

        treeNode* res = Build(pre, in);
        postOrder(res);
        cout << endl;
    }
}

9.2 根据前序序列构成二叉树

二叉树遍历_牛客题霸_牛客网 (nowcoder.com)

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstring>
#include<string>

using namespace std;

struct treeNode {
    char data;
    treeNode* leftChild;
    treeNode* rightChild;
    treeNode(char c): data(c), leftChild(nullptr), rightChild(nullptr) {};
};


void inOrder(treeNode* root) {
    if (root == nullptr) return;
    inOrder(root->leftChild);
    cout << root->data << ' ';
    inOrder(root->rightChild);

}

string arr;
int index1 = 0;
treeNode* createTree() {

    if (arr[index1] == '#') {
        index1++;
        return nullptr;
    }
    treeNode* root = new treeNode(arr[index1++]);
    root->leftChild = createTree();
    root->rightChild = createTree();
    return root;


}

int main() {
    while (cin >> arr) {
        index1=0;
        treeNode* res = createTree();
        inOrder(res);
        cout << endl;
    }


}

9.3 二叉排序树的生成

二叉排序树_牛客题霸_牛客网 (nowcoder.com)

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstring>
#include<string>

using namespace std;

struct treeNode {
    int data;
    treeNode* leftChild;
    treeNode* rightChild;
    treeNode(int c): data(c), leftChild(nullptr), rightChild(nullptr) {};
};

treeNode* insert(treeNode* root, int x) {
    if (root == nullptr) {
        root = new treeNode(x);

    } else if (x < root->data) {
        root->leftChild = insert(root->leftChild, x);
    } else if (x > root->data) {
        root->rightChild = insert(root->rightChild, x);
    }

    return root;
}

void preOrder(treeNode* root) {
    if (root == nullptr) return;
    cout << root->data << " ";
    preOrder(root->leftChild);
    preOrder(root->rightChild);
}

void inOrder(treeNode* root) {
    if (root == nullptr) return;

    inOrder(root->leftChild);
    cout << root->data << " ";
    inOrder(root->rightChild);
}
void postOrder(treeNode* root) {
    if (root == nullptr) return;
    postOrder(root->leftChild);
    postOrder(root->rightChild);
    cout << root->data << " ";
}

int main() {
    int n;
    int a;
    while (cin >> n) {
        treeNode* root = nullptr;
        for (int i = 0; i < n; i++) {
            cin >> a;
            root = insert(root, a);
        }
        preOrder(root);
        cout << endl;
        inOrder(root);
        cout << endl;
        postOrder(root);

        cout << endl;
    }
}

9.4 记录插入结点的父节点

二叉排序树_牛客题霸_牛客网 (nowcoder.com)

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstring>
#include<string>

using namespace std;

struct treeNode {
    int data;
    treeNode* leftChild;
    treeNode* rightChild;
    treeNode(int c): data(c), leftChild(nullptr), rightChild(nullptr) {};
};

treeNode* insert(treeNode* root, int x, int parent) {
    if (root == nullptr) {
        root = new treeNode(x);
        cout << parent << endl;

    } else if (x < root->data) {
        root->leftChild = insert(root->leftChild, x, root->data);
    } else if (x > root->data) {
        root->rightChild = insert(root->rightChild, x, root->data);
    }

    return root;
}
int main() {
    int n;
    int a;
    while (cin >> n) {
        treeNode* root = nullptr;
        for (int i = 0; i < n; i++) {
            cin >> a;
            root = insert(root, a, -1);
        }
    }
}

9.5 判断两棵二叉树是否相同

二叉搜索树_牛客题霸_牛客网 (nowcoder.com)

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstring>
#include<string>

using namespace std;

struct treeNode {
    int data;
    treeNode* leftChild;
    treeNode* rightChild;
    treeNode(int c): data(c), leftChild(nullptr), rightChild(nullptr) {};
};

treeNode* insert(treeNode* root, int data) {
    if (root == nullptr) {
        root = new treeNode(data);
    } else if (data < root->data) {
        root->leftChild = insert(root->leftChild, data);
    } else if (data > root->data) {
        root->rightChild = insert(root->rightChild, data);
    }
    return root;
}

bool judge(treeNode* t1, treeNode* t2) {
    if (t1 == nullptr && t2 == nullptr) return true;
    else {
        if (t1 == nullptr || t2 == nullptr) return false;
        else {
            if (t1->data == t2->data) {
                return judge(t1->leftChild, t2->leftChild) &&
                       judge(t1->rightChild, t2->rightChild);
            } else {
                return false;
            }
        }
    }
}
int main() {
    int n;
    int a;
    string arr;
    while (cin >> n) {
        if (n == 0) break;
        treeNode* root = nullptr;
        cin >> arr;
        for (int i = 0; i < arr.size(); i++) {
            root = insert(root, arr[i] - '0');
        }

        while (n--) {
            treeNode* tmp = nullptr;
            cin >> arr;
            for (int  i = 0; i < arr.size(); i++) {
                tmp = insert(tmp, arr[i] - '0');
            }

            if (judge(root, tmp)) {
                cout << "YES" << endl;
            } else {
                cout << "NO" << endl;
            }


        }

    }
}

9.4 记录插入结点的父节点

二叉排序树_牛客题霸_牛客网 (nowcoder.com)

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstring>
#include<string>

using namespace std;

struct treeNode {
    int data;
    treeNode* leftChild;
    treeNode* rightChild;
    treeNode(int c): data(c), leftChild(nullptr), rightChild(nullptr) {};
};

treeNode* insert(treeNode* root, int x, int parent) {
    if (root == nullptr) {
        root = new treeNode(x);
        cout << parent << endl;

    } else if (x < root->data) {
        root->leftChild = insert(root->leftChild, x, root->data);
    } else if (x > root->data) {
        root->rightChild = insert(root->rightChild, x, root->data);
    }

    return root;
}
int main() {
    int n;
    int a;
    while (cin >> n) {
        treeNode* root = nullptr;
        for (int i = 0; i < n; i++) {
            cin >> a;
            root = insert(root, a, -1);
        }
    }
}

9.5 判断两棵二叉树是否相同

二叉搜索树_牛客题霸_牛客网 (nowcoder.com)

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstring>
#include<string>

using namespace std;

struct treeNode {
    int data;
    treeNode* leftChild;
    treeNode* rightChild;
    treeNode(int c): data(c), leftChild(nullptr), rightChild(nullptr) {};
};

treeNode* insert(treeNode* root, int data) {
    if (root == nullptr) {
        root = new treeNode(data);
    } else if (data < root->data) {
        root->leftChild = insert(root->leftChild, data);
    } else if (data > root->data) {
        root->rightChild = insert(root->rightChild, data);
    }
    return root;
}

bool judge(treeNode* t1, treeNode* t2) {
    if (t1 == nullptr && t2 == nullptr) return true;
    else {
        if (t1 == nullptr || t2 == nullptr) return false;
        else {
            if (t1->data == t2->data) {
                return judge(t1->leftChild, t2->leftChild) &&
                       judge(t1->rightChild, t2->rightChild);
            } else {
                return false;
            }
        }
    }
}
int main() {
    int n;
    int a;
    string arr;
    while (cin >> n) {
        if (n == 0) break;
        treeNode* root = nullptr;
        cin >> arr;
        for (int i = 0; i < arr.size(); i++) {
            root = insert(root, arr[i] - '0');
        }

        while (n--) {
            treeNode* tmp = nullptr;
            cin >> arr;
            for (int  i = 0; i < arr.size(); i++) {
                tmp = insert(tmp, arr[i] - '0');
            }

            if (judge(root, tmp)) {
                cout << "YES" << endl;
            } else {
                cout << "NO" << endl;
            }


        }

    }
}

9.6 查找第k小数

本题重点在排除重复的数

查找第K小数_牛客题霸_牛客网 (nowcoder.com)

#include <iostream>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 1e4 + 10;
int main() {
    int n, c;
    int arr[maxn];
    while (cin >> n) { // 注意 while 处理多个 case
        memset(arr, 0, sizeof(arr));
        vector<int> vec;
        while (n--) {
            cin >> c;
            if (arr[c] == 1) continue;
            arr[c] = 1;
            vec.push_back(c);
        }
        sort(vec.begin(), vec.end());
        int k;
        cin >> k;
        cout << vec[k - 1] << endl;
    }
}
  • 3
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值