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

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

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

文章目录

  • 计算机考研复试上机算法学习
    • 1.STL容器学习
      • 1.1 vector动态数组
        • 1.1.1 完数VS盈数
      • 1.2 stack栈
        • 1.2.1 逆序输出
        • 1.2.2 后缀运算符
        • 1.2.3 堆栈的使用
      • 1.3 queue队列
        • 1.3.1 实现循环队列来解决约瑟夫问题
      • 1.4 priority_queue优先队列
        • 1.4.1 优先队列解决复数集合问题
        • 1.4.2 优先队列解决哈夫曼树问题
      • 1.5 双向链表 list
      • 1.6 set集合
      • 1.7 map映射容器
        • 1.7.1 map的应用
        • 1.7.2 统计字符串出现次数
        • 1.7.3 查询分数
        • 1.7.4 开门人 和关门人
        • 1.7.5 谁是你的潜在朋友
      • 1.8 sort排序函数
      • 1.9 next_permutation函数
    • 2.算法学习
      • 2.1 递归实现求元素的全排列
      • 2.2 反序数
      • 2.3百鸡问题
      • 2.4 火鸡账单
      • 2.5 今年的第几天
      • 2.6打印日期
      • 2.7 日期累加
      • 2.8 [日期差值_牛客题霸_牛客网 (nowcoder.com)](https://www.nowcoder.com/practice/ccb7383c76fc48d2bbc27a2a6319631c?tpId=40&tqId=21442&tPage=1&rp=1&ru=/ta/kaoyan&qru=/ta/kaoyan/question-ranking)
      • 2.9 [Day of Week_牛客题霸_牛客网 (nowcoder.com)](https://www.nowcoder.com/practice/a3417270d1c0421587a60b93cdacbca0?tpId=40&tqId=21439&tPage=1&rp=1&ru=/ta/kaoyan&qru=/ta/kaoyan/question-ranking)
      • 2.10[剩下的树_牛客题霸_牛客网 (nowcoder.com)](https://www.nowcoder.com/practice/f5787c69f5cf41499ba4706bc93700a2?tpId=60&tqId=29497&tPage=2&ru=/kaoyan/retest/1001&qru=/ta/tsing-kaoyan/question-ranking)
      • 2.11[xxx定律_牛客题霸_牛客网 (nowcoder.com)](https://www.nowcoder.com/practice/75c189249d6145cfa33cd53edae6afc8?tpId=63&tqId=29579&tPage=1&ru=/kaoyan/retest/9001&qru=/ta/zju-kaoyan/question-ranking)
      • 2.12 排序题
      • 2.13带学号的成绩排序问题
      • 2.14 考虑输入次序的学生成绩排序
      • 2.15特殊排序
      • 2.16 整数奇偶排序(简单)
      • 2.17 小白鼠排序
      • 2.18 奥运排序问题
      • 2.19多次查找
      • 2.20找最小数
      • 2.21 找位置
    • 3.字符串习题
      • ****字符串的一些用法***
      • 3.1 特殊乘法
      • 3.2字符转换
      • 3.3 密码转换
      • 3.4 计算字符出现次数
      • 3.5 统计大写字母出现次数
      • 3.6 SKEW数
      • 3.7 查找字符串
      • 3.8 将单词首字母转换成大写
      • 3.9 浮点数加法
      • 3.10 使用KMP求字符串完全匹配次数
    • 4.特殊的数学问题
      • 4.1十进制转二进制
      • 4.2 使用大数除法的十进制转二进制
      • 4.3 二进制转十进制
      • 4.4 M进制转换成N进制
      • 4.5 十进制转八进制
      • 4.6 A+B 转m进制
      • 4.7 十六进制转十进制
      • 4.8 数制转换
      • 4.9 最大公约数
      • 4.10 最小公倍数
      • 4.11 判断最简真分数
      • 4.12 判断是否是素数
      • 4.13 输出个位数为1的素数
      • 4.14 质因数
      • 4.15 约数的个数
      • 4.16 整除问题
      • 4.17 快速幂的应用
      • 4.18 矩阵乘法
      • 4.19 矩阵快速幂
      • 4.20 矩阵加法
    • 5.贪心算法
      • 5.1匹配服务器
      • 5.2 区间贪心:看电视节目
      • 5.3 油价
    • 6.递归与分治
      • 6.1 n的阶乘
      • 6.2 杨辉三角
      • 6.3 全排列(元素个数与之前一样)
      • 6.4 斐波那契数列
      • 6.5 求完全二叉树结点的子树
      • 6.6分解数字转二的次幂
    • 7.搜索算法
      • 7.1 广度优先算法
      • 7.2 广度优先解决玛雅密码问题
      • 7.3 深度优先算法搜索状态问题
      • 7.4 神奇的口袋
      • 7.4 八皇后问题
    • 8.动态规划
      • 8.1 上楼梯
      • 8.2 吃糖果
      • 8.3 最长子序列和
      • 8.4 最长递增子序列
      • 8.5 最大递增子序列2
      • 8.6 最长不递增子序列
      • 8.7 最大上升子序列和
      • 8.8 合唱队形
      • 8.9 0-1背包问题,同一件物品最多只能选择一件
      • 8.11 最小邮票数
      • 8.12 完全背包
      • 8.13 多重背包
      • 8.14 三角形
      • 8.15 [题解 | #Monkey Banana Problem#_牛客网 (nowcoder.com)](https://www.nowcoder.com/discuss/454400979698528256?sourceSSR=post)
      • 8.16 放苹果
      • 8.17 划分
    • 9.二叉树
      • 9.1 根据前序和中序生成二叉树序列
      • 9.2 根据前序序列构成二叉树
      • 9.3 二叉排序树的生成
      • 9.4 记录插入结点的父节点
      • 9.5 判断两棵二叉树是否相同
      • 9.4 记录插入结点的父节点
      • 9.5 判断两棵二叉树是否相同
      • 9.6 查找第k小数

1.STL容器学习

1.1 vector动态数组

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

#定义vector动态数组
vector a;
vector a;
a.push_back(500);//插入数据
a.insert(a.begin(),99);//在对应元素前面插入99
a.erase(a.begin()+1);//删除对应位置得到数据
cout<

1.1.1 完数VS盈数

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

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

#include 
#include
using namespace std;

int main() {
    vector e;
    vector g;
    for(int nums=2;nums<=60;nums++){
        int res =0;
        for(int i=1;inums) g.push_back(nums);
        }
    }
    cout<<"E:";
    for(int i=0;i

1.2 stack栈

stack st;
st.push(1);//插入元素到栈顶
    cout<

1.2.1 逆序输出

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

#include 
#include
using namespace std;

int main() {
    int n;
    while(cin>>n){
        stack s;
        int k;
        for(int i=0;i>k;
            s.push(k);
        }
        while(!s.empty()){
            cout<

1.2.2 后缀运算符

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

#include 
#include
#include
#include 
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 m;
    m['+'] = 1;
    m['-'] = 1;
    m['*'] = 2;
    m['/'] = 2;

    while (getline(cin, str)) {
        if (str == "0") break;
        stack s1;
        stack 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 
#include
#include
#include 
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 m;
    m['+'] = 1;
    m['-'] = 1;
    m['*'] = 2;
    m['/'] = 2;

    while (getline(cin, str)) {
        if (str == "0") break;
        stack s1;
        stack 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 
#include
using namespace std;

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

1.3 queue队列

queue s;//创造队列
 s.push(100);
 s.push(1000);
 s.pop();//删除队首元素
 //front访问对首位置,back访问队尾位置
 cout<

1.3.1 实现循环队列来解决约瑟夫问题

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

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

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

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

#include 
#include
using namespace std;
int main() {
    int n,p,m;
    cin>>n>>p>>m;
    queue children;
    for(int i=1;i<=n;i++){
        children.push(i);
    }
    for(int i=1;i

1.4 priority_queue优先队列

  • 头文件:include

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

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

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

    //方式一
    priority_queue pq;
    //方式二
    priority_queue,greater> pq;//升序排列
    priority_queue,less> pq;//降序排列
    pq.top();//队首元素
    pq.pop();//出队
    

    1.4.1 优先队列解决复数集合问题

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

    #include
    #include
    #include
    #include
    #include
    #include
    
    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>n){
            priority_queue pq;
            while(n--){
                cin>>str;
                if(str=="Pop"){
                    if(pq.empty()){
                        cout<<"empty"<

1.4.2 优先队列解决哈夫曼树问题

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

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

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 a;//定义
set::iterator it;
a.insert(100);//插入元素100
a.insert(100);
a.insert(101);
cout<

1.7 map映射容器

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

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

#include 
#include 
#include 

using namespace std;

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

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

    //查
    cout<::iterator it;
    for(it=myMap.begin();it!=myMap.end();it++){
        cout << it->first <<" "<second<

1.7.1 map的应用

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

#include 
#include
#include
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 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 
#include
#include
using namespace std;

int main() {
    int a, b;
    map 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::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 
#include
using namespace std;

int main() {
    int n;
    mapm;
    int score;
    while (cin >> n) { // 注意 while 处理多个 case
        if(n==0) break;
        m.clear();
        while(n--){
            cin>>score;
            m[score]+=1;
        }
        cin>>score;
        cout<

1.7.4 开门人 和关门人

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

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

#include 
#include
using namespace std;

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

1.7.5 谁是你的潜在朋友

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

#include 
#include
#include
using namespace std;
int main() {
    int n, m;
    map table;
    vector 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//需要引用头文件
bool compare(point p1, point p2){
    return p1.x>p2.x;//按x从大到小排序
}
list l1;
sort(l1.begin(),l1.end(),compare);

1.9 next_permutation函数

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

    int num[3] = {1,2,3};
    do{
        cout<

2.算法学习

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

int num[3] = {3, 2, 1};
int Perm(int begin, int end){
    int i;
    if(begin == end){
        cout<

2.2 反序数

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

#include 
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<

2.3百鸡问题

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

#include 
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 
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 
#include 
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

2.6打印日期

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

#include 
#include 
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 
#include 
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> year >>month>> day>> addDay;
    solve(year,  month, day, addDay);   
    }

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

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

#include 
#include 
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 
#include 
#include
#include
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 m;
    map 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 
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>left>>right;
        for(i=left;i<=right;i++){
            if(tree[i]){//如果以及被移除便不再处理
                tree[i] = false;
                num--;
            }
        }
    }
    cout<

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

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

#include 
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<> a ) { // 注意 while 处理多个 case
        solve(a);
    }
}
// 64 位输出请用 printf("%lld")

2.12 排序题

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

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

2.13带学号的成绩排序问题

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

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

#include 
#include
#include
#include
using namespace std;

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

bool compare(students s1, students s2){
    if(s1.score==s2.score) 
        return s1.num vec;
    int num;
    while (cin >> num) { // 注意 while 处理多个 case
    for(int i=0;i>stu.num>>stu.score;
        vec.push_back(stu);
    }
    sort(vec.begin(),vec.end(),compare);
    for(int i=0;i

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

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

#include 
#include
#include
#include
#include
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.score;


}

int main() {
    vector 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 
#include
#include
#include
#include
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 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 
#include
#include
using namespace std;

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

int main() {
    int b,i,j;
    int a[10]={0};
    vector vec1;//存放奇数的数组
    vector 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

2.17 小白鼠排序

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

#include 
#include
#include
#include
#include
using namespace std;

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

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

}

int main() {
    vector 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 
#include
#include
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 vec;
    vector 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 
#include
#include
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){
            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 
#include
#include
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 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 
#include 
using namespace std;
int main() {
    string str;
    while(cin>>str){
        for(int i=0;i

3.字符串习题

*字符串的一些用法

s

3.1 特殊乘法

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

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

#include 
#include

using namespace std;

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

3.2字符转换

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

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

#include 
#include
using namespace std;

int main() {
    // int a, b;
    string a;
    while (getline(cin,a)) { // 注意 while 处理多个 case
        for(int i=0;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<

3.3 密码转换

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

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

#include 
#include 
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='A'&&str[i]<='Z'){
            str[i] =((str[i]-'A'-5+26)%26) +'A';//将数字转换成字母表中循环向前移动五位
            }
        }
        cout<

3.4 计算字符出现次数

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

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

#include 
#include
#include//memset的头文件
#include
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

3.5 统计大写字母出现次数

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

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

#include 
#include
#include
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 
#include
#include
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 
#include 
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 
#include

using namespace std;

int main() {
    string str;
    while(getline(cin,str)){
        char ch ='a';
        for(int i=0;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<

3.9 浮点数加法

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

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

//这里我先将两个字符串小数点前后补齐到相同的长度,再一一对位相加 (这里记得进位
#include 
#include
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=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<

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

#include 
#include
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

4.特殊的数学问题

4.1十进制转二进制

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

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

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

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

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

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

#include 
#include
#include
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 
#include
#include
#include
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 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

4.4 M进制转换成N进制

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

#include 
#include 
#include
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 s;
    while (cin >> a >> b) { // 注意 while 处理多个 case
        cin>>str;
        long long ans =0;//这里记得使用long long数据类型
        for(int i=0;i

4.5 十进制转八进制

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

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

4.6 A+B 转m进制

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

#include 
#include
using namespace std;
int main() {
    long long a,b,m;//使用长整型防止超过表示范围
    stack 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 
#include 
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

4.8 数制转换

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

#include 
#include 
#include
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 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 
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 
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 
#include
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 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 
#include
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"<

4.13 输出个位数为1的素数

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

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

#include 
#include
#include
#include
using namespace std;
#define MAXN 1000000
bool isPrime[MAXN];
vector 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> a ) { // 注意 while 处理多个 case
        int i=0;
        int flag=0;
        while(prime[i]<=a){
            if(prime[i]%10==1){
                if(flag) cout<<" ";
                cout<

4.14 质因数

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

#include
#include
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
#include
#include
using namespace std;


int main() {
    int num;
    vector  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
#include

using namespace std;
//统计 num 中的质因子数
void getPrime(vector& 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 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 
#include
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 
#include
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 
#include
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 
#include
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
#include
#include

using namespace std;

int getCnt(vector& proxy, vector& server, int m) {
    int  index=0;
    int count=0;
    while(index> n) {
        vector proxy(n);
        for (int i = 0; i < n; i ++) {
            cin >> proxy[i];
        }
        cin >> m;
        vector server(m);
        for (int i = 0; i < m; i ++)
            cin >> server[i];
        cout << getCnt(proxy, server, m);
    }
}

5.2 区间贪心:看电视节目

#include
#include
#include
#include
using namespace std;

struct tv{
    int start;
    int end;
};

bool compare(tv a, tv b){
    return a.end dianshi;
    while (cin >> n) {
        for(int i=0;i>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

5.3 油价

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

#include 
#include 
#include 
/*
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 
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
using namespace std;
void solve(int n){
    int Matrix[n][n];
    for(int i=0;i>a){
     solve(a);
    }
}

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

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

#include
#include
#include
#include
using namespace std;
string a;


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

6.4 斐波那契数列

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

#include 
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 
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<

6.6分解数字转二的次幂

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

#include 
#include
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 vec;
        while (n != 0) {
            vec.push_back(n % 2);
            n /= 2;
        }
        vector 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
#include
#include
#include
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){
    queuemyQueue;
   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<

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

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

#include
#include
#include
#include
#include
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 m;
    queue 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
#include
#include
#include
#include
#include
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;iside||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>sticks[i];
        length+=sticks[i];
    }
    if(length%4!=0){
        cout<<"no"<side){
            cout<<"no";
        }
        else if(DFS(0,0,0)){
            cout<<"yes"<

7.4 神奇的口袋

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

#include 
#include
#include
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<

7.4 八皇后问题

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

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

#include 
#include
#include
using namespace std;
vector vec;
int visit[9];
int arr[9];
bool judge(int k, int a){
    for(int i=1;i>n){
        cout<

8.动态规划

8.1 上楼梯

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

#include 
#include 
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<

8.2 吃糖果

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

#include 
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<

8.3 最长子序列和

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

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

#include 
#include 
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 
#include 
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) { // 注意 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 
#include 
#include
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){
    for(int i=0;i>matrix[i][j];
        }
    }
    for(int i=0;i

8.5 最大递增子序列2

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

#include 
#include 
#include 
#include
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]> n) { // 注意 while 处理多个 case
        if(n==0) break;
        int flag=0;
        memset(memo,0,sizeof(memo));
        for(int i=0;i>arr[i];
            if(arr[i]>=0) flag=1;
            start[i]=arr[i];//起始是自己
        }
        if(flag==0)  cout<<0<<" "<

8.6 最长不递增子序列

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

#include 
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=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>arr[i];
        }
        cout<

8.7 最大上升子序列和

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

#include 
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>arr[i];
    }
    support[0]=-maxn;
    int length=0;
    for(int i=0;i

8.8 合唱队形

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

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

#include 
#include
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;ians){
                ans =dp[i]+dp2[i];
            }
        }
        cout << (n - ans+1) << endl;
    }
}

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

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

#include 
#include
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

空间优化版本:

#include 
#include
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<

采药__牛客网 (nowcoder.com)

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

8.11 最小邮票数

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

#include
#include
#include

using namespace std;

const int MAX = 100000;

int main() {
    int m, n;
    while (cin >> m >> n) {
        vector stamps(n + 1, 0);
        vector 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
#include
#include
#include
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<

8.13 多重背包

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

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

#include 
#include
#include
#include
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>amount[i]>>weight[i]>>value[i];
    }
    int num=0;
    for(int i=0;i0){
            newWeight[num]=weight[i]*amount[i];
            newValue[num]=value[i]*amount[i];
            num++;

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

    cout<

8.14 三角形

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

#include 
#include
#include
#include
using namespace std;
const int maxn = 1001;
class Solution {
public:
    int minimumTotal(vector > &triangle) {
        int res[maxn][maxn];
       
        int n=triangle.size();
        for (int i = 0; i < n; ++i) {
        for (int j = 0; j <= i; ++j) {
            vector 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
#include
#include
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> dp(M + 1, vector(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
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
#include
#include
#include
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
#include
#include
#include
#include
#include

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
#include
#include
#include
#include
#include

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
#include
#include
#include
#include
#include

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
#include
#include
#include
#include
#include

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
#include
#include
#include
#include
#include

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
#include
#include
#include
#include
#include

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 
#include
#include
#include
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 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;
    }
}

你可能感兴趣的:(考研,算法,学习)