作者: domain

  • 扑克牌排序(结构体)

    时间限制: 1 Sec 内存限制: 128 MB

    题目描述

    自定义结构体表示一张扑克牌,包含类型——黑桃、红桃、梅花、方块、王;大小——2,3,4,5,6,7,8,9,10,J,Q,K,A,小王(用0表示)、大王(用1表示)。输入n,输入n张扑克牌信息,从大到小输出它们的排序结果。
    假设扑克牌的排序规则是大王、小王为第一大、第二大,剩余52张扑克牌按照先花色后大小排序。
    花色:黑桃>红桃>梅花>方块。
    大小: A>K>Q>J>>10>9>…>2。
    提示:百度sort函数、strstr函数使用。

    输入

    测试次数t
    每组测试数据两行:
    第一行:n,表示输入n张扑克牌
    第二行:n张扑克牌信息,格式见样例

    输出

    对每组测试数据,输出从大到小的排序结果

    样例输入

    3
    5
    黑桃4 红桃10 梅花Q 方块K 黑桃A
    10
    大王 梅花10 红桃K 方块9 黑桃2 梅花A 方块Q 小王 黑桃8 黑桃J
    5
    红桃K 梅花K 黑桃K 方块K 小王

    样例输出

    黑桃A 黑桃4 红桃10 梅花Q 方块K
    大王 小王 黑桃J 黑桃8 黑桃2 红桃K 梅花A 梅花10 方块Q 方块9
    小王 黑桃K 红桃K 梅花K 方块K

    提示

    解决方案

    #include <iostream>
    #include <string>
    #include <vector>
    #include <algorithm>
    #include <assert.h>
    
    class Poker {
    public:
        friend std::istream &operator>>(std::istream &in, Poker &poker) {
            in >> poker.info;
            return in;
        }
    
        friend std::ostream &operator<<(std::ostream &out, const Poker &poker) {
            out << poker.info;
            return out;
        }
    
        bool operator<(const Poker &rhs) const {
            if (this->typeValue() != rhs.typeValue()) {
                return this->typeValue() < rhs.typeValue();
            } else {
                return this->sizeValue() < rhs.sizeValue();
            }
        }
    
    private:
        std::string info;
    
        int typeValue() const {
            std::string type;
            if (info.find("大王") != std::string::npos) {
                return 6;
            } else if (info.find("小王") != std::string::npos) {
                return 5;
            } else if (info.find("黑桃") != std::string::npos) {
                return 4;
            } else if (info.find("红桃") != std::string::npos) {
                return 3;
            } else if (info.find("梅花") != std::string::npos) {
                return 2;
            } else if (info.find("方块") != std::string::npos) {
                return 1;
            }
            assert(0);
        }
    
        int sizeValue() const {
            char back = info[info.length() - 1];
            switch (back) {
                default:
                    return back - '0';
                case '0':
                    return 10;
                case 'J':
                    return 11;
                case 'Q':
                    return 12;
                case 'K':
                    return 13;
                case 'A':
                    return 14;
            }
        }
    };
    
    int main() {
        size_t T;
        std::cin >> T;
    
        while (T--) {
            size_t size;
            std::cin >> size;
            std::vector<Poker> vector(size);
            for (size_t i = 0; i < vector.size(); ++i) {
                std::cin >> vector[i];
            }
    
            std::sort(vector.rbegin(), vector.rend());
    
            std::cout << vector.front();
            for (size_t i = 1; i < vector.size(); ++i) {
                std::cout << ' ' << vector[i];
            }
            std::cout << std::endl;
        }
    
        return 0;
    }
    

    引用

    Check if a string contains a string in C++ – Stack Overflow
    c++ – Does Overloading Operator<< works inside the class? – Stack Overflow
    sort – C++ Reference

  • 矩阵类模板(类模板)

    时间限制: 1 Sec 内存限制: 128 MB

    题目描述

    设计一个矩阵类模板Matrix,支持任意数据类型的数据。
    要求至少包含2个成员函数:矩阵转置函数transport、以及打印输出函数print
    编写main函数进行测试,调用类的成员函数完成转置和输出。

    输入

    第一行先输入t,表示有t个测试用例
    从第二行开始输入每个测试用例的数据。
    首先输入数据类型,I表示int,D表示double,C表示char,接着输入两个参数m和n,分别表示矩阵的行和列
    接下来输入矩阵的元素,一共m行,每行n个数据

    输出

    输出转置后的矩阵

    样例输入

    2
    I 2 3
    1 2 3
    4 5 6
    C 3 3
    a b c
    d e f
    g h i

    样例输出

    1 4
    2 5
    3 6
    a d g
    b e h
    c f i

    提示

    解决方案

    #include <iostream>
    
    template<typename T>
    class Matrix {
    public:
        Matrix(size_t row, size_t col) : row(row), col(col) {
            data = new T *[row];
            for (size_t i = 0; i < row; ++i) {
                data[i] = new T[col];
            }
        }
    
        void setFromCin() {
            for (size_t ir = 0; ir < row; ++ir) {
                for (size_t ic = 0; ic < col; ++ic) {
                    std::cin >> data[ir][ic];
                }
            }
        }
    
        void transport() {
            T **tmp = new T *[col];
            for (size_t ir = 0; ir < col; ++ir) {
                tmp[ir] = new T[row];
            }
            for (size_t ir = 0; ir < col; ++ir) {
                for (size_t ic = 0; ic < row; ++ic) {
                    tmp[ir][ic] = data[ic][ir];
                }
            }
    
            for (size_t ir = 0; ir < row; ++ir) {
                delete[](data[ir]);
            }
            delete[](data);
            std::swap(row, col);
            data = tmp;
        }
    
        void println() {
            for (size_t ir = 0; ir < row; ++ir) {
                std::cout << data[ir][0];
                for (size_t ic = 1; ic < col; ++ic) {
                    std::cout << ' ' << data[ir][ic];
                }
                std::cout << std::endl;
            }
        }
    
        struct Row &operator[](int index) {
            return Row(data[index]);
        }
    
        ~Matrix() {
            for (size_t ir = 0; ir < row; ++ir) {
                delete[](data[ir]);
            }
            delete[](data);
        }
    
    private:
        int row, col;
        T **data;
    
        struct Row {
            explicit Row(T *row) : data(row) {}
    
            T operator[](int index) {
                return data[index];
            }
    
            T *data;
        };
    };
    
    int main() {
        int T;
        std::cin >> T;
    
        while (T--) {
            char type;
            std::cin >> type;
            int row, col;
            std::cin >> row >> col;
            switch (type) {
                case 'I': {
                    Matrix<int> matrix(row, col);
                    matrix.setFromCin();
                    matrix.transport();
                    matrix.println();
                    break;
                }
                case 'D': {
                    Matrix<double> matrix(row, col);
                    matrix.setFromCin();
                    matrix.transport();
                    matrix.println();
                    break;
                }
                case 'C': {
                    Matrix<char> matrix(row, col);
                    matrix.setFromCin();
                    matrix.transport();
                    matrix.println();
                    break;
                }
                default: ;
            }
        }
    
        return 0;
    }
    
  • 动态矩阵(指针与堆内存分配)

    时间限制: 1 Sec 内存限制: 128 MB

    题目描述

    未知一个整数矩阵的大小,在程序运行时才会输入矩阵的行数m和列数n
    要求使用指针,结合new方法,动态创建一个二维数组,并求出该矩阵的最小值和最大值,可以使用数组下标法。
    不能先创建一个超大矩阵,然后只使用矩阵的一部分空间来进行数据访问、
    创建的矩阵大小必须和输入的行数m和列数n一样

    输入

    第一行输入t表示t个测试实例
    第二行输入两个数字m和n,表示第一个矩阵的行数和列数
    第三行起,连续输入m行,每行n个数字,表示输入第一个矩阵的数值
    依次输入t个实例

    输出

    每行输出一个实例的最小值和最大值

    样例输入

    2
    2 3
    33 22 11
    66 88 55
    3 4
    19 38 45 14
    22 65 87 31
    91 35 52 74

    样例输出

    11 88
    14 91

    提示

    解决方案

    #include <iostream>
    
    int main() {
        size_t T;
        std::cin >> T;
    
        while (T--) {
            size_t row, col;
            std::cin >> row >> col;
            int **matrix = new int *[row];
            for (size_t ir = 0; ir < row; ++ir) {
                matrix[ir] = new int[col];
                for (size_t ic = 0; ic < col; ++ic) {
                    std::cin >> matrix[ir][ic];
                }
            }
            int min = matrix[0][0], max = matrix[0][0];
            for (size_t ir = 0; ir < row; ++ir) {
                for (size_t ic = 0; ic < col; ++ic) {
                    if (min > matrix[ir][ic]) {
                        min = matrix[ir][ic];
                    }
                    if (max < matrix[ir][ic]) {
                        max = matrix[ir][ic];
                    }
                }
            }
            std::cout << min << ' ' << max << std::endl;
        }
    
        return 0;
    }
    
  • 三串合一(指针与字符数组)

    时间限制: 1 Sec 内存限制: 128 MB

    题目描述

    输入三个字符串,通过指针读取各个字符串的子串(子串是指字符串中连续的一小部分),把它们合并成一个新字符串

    要求:

    1. 三个字符串的创建和输入可以使用数组,也可以不用
    2. 输入后,根据三个字符串的子串的长度,计算出新字符串的长度
    3. 使用动态数组的方法创建新的字符串,并且使用指针读取三个字符串的不同部分,并且复制到新字符串中,要求整个过程都不能使用数组下标
    4. 使用指针输出新的字符串

    输入

    第一行输入t表示有t个测试实例
    连续三行输入三个字符串,每个字符串都包含10个字符
    连续三行,每行输入数字a和b,表示每个子串的开始和结束位置。注意字符串的位置是按照一般意义从1开始计算,和编程中的数组位置不同。例如字符串abcdefg,开始位置是3,结束位置是5,那么子串就是cde
    依次输入t个实例

    输出

    每行输出合并后的新字符串

    样例输入

    2
    abcdefghij
    ABCDEFGHIJ
    aabbccddee
    3 5
    2 6
    8 10
    AABBCCDDEE
    ffgghhiijj
    FFGGHHIIJJ
    1 4
    5 8
    2 7

    样例输出

    cdeBCDEFdee
    AABBhhiiFGGHHI

    提示

    解决方案

    #include <iostream>
    
    int main() {
        size_t T;
        std::cin >> T;
    
        while (T--) {
            char strings[3][16];
            std::cin >> strings[0] >> strings[1] >> strings[2];
            size_t bound[3][2] = {}, size = 0;
            for (size_t ir = 0; ir < 3; ++ir) {
                for (size_t ic = 0; ic < 2; ++ic) {
                    std::cin >> bound[ir][ic];
                    bound[ir][ic] -= 1;
                }
                size += (bound[ir][1] - bound[ir][0]);
            }
            char *string = new char[size + 1];
            char *dst = string;
            for (size_t i = 0; i < 3; ++i) {
                char *src = strings[i] + bound[i][0];
                while (src <= strings[i] + bound[i][1]) {
                    *dst++ = *src++;
                }
            }
            *dst = '\0';
            std::cout << string << std::endl;
        }
    
        return 0;
    }
    
  • 鸡蛋队列(数组,函数)

    时间限制: 1 Sec 内存限制: 128 MB

    题目描述

    将两根筷子平行的放在一起,就构成了一个队列。将带有编号的鸡蛋放到两根筷子之间叫做入队(push),将筷子之间的鸡蛋拿出来叫做出队(pop)。但这两种方式有特殊的定义,对于入队,只能将鸡蛋从队列的尾部向里放入;对于出队,只能将鸡蛋从队列的头部向外将鸡蛋拿出来。

    输入

    第一行输入一个数T,表示有T组数据 第二行输入一个数N,表示有N(N<=10)种操作 接下来N行,每行一种操作,push表示将编号为x的鸡蛋放入队列中,pop表示拿走队列头部的一个鸡蛋。 数据输入保证合法,队列中没有鸡蛋时不会有出队操作!

    输出

    输出N种操作完之后,队列中蛋蛋的编号,如果没蛋了,就输出”no eggs!”(不包括引号)每组输出占一行。

    样例输入

    2
    3
    push 1 
    push 2
    push 3
    2
    push 1
    pop

    样例输出

    1 2 3
    no eggs!

    提示

    数组模拟队列,用下标记录对头、队尾位置。

    解决方案

    #include <stdio.h>
    
    struct Queue {
        int data[32];
        int head, tail;
    };
    
    void push(struct Queue *queue, int data);
    void pop(struct Queue *queue);
    void show(struct Queue *queue);
    
    int main() {
        int ctrl;
        scanf("%d", &ctrl);
    
        while (ctrl--) {
            struct Queue queue = {};
            int time;
            scanf("%d", &time);
            while (time--) {
                char operation[8];
                scanf("%s", operation);
                if (operation[1] == 'u') {
                    int data;
                    scanf("%d", &data);
                    push(&queue, data);
                } else {
                    pop(&queue);
                }
            }
            show(&queue);
        }
    
        return 0;
    }
    
    void push(struct Queue *queue, int data) {
        queue->data[queue->tail] = data;
        queue->tail += 1;
    }
    
    void pop(struct Queue *queue) {
        queue->head += 1;
    }
    
    void show(struct Queue *queue) {
        if (queue->head == queue->tail) {
            printf("no eggs!\n");
        } else {
            printf("%d", queue->data[queue->head]);
            for (int i = queue->head + 1; i != queue->tail; ++i) {
                printf(" %d", queue->data[i]);
            }
            printf("\n");
        }
    }
    
  • 分类排序(函数)

    时间限制: 1 Sec 内存限制: 128 MB

    题目描述

    从键盘输入10个整数(10个整数均不相同), 然后再从键盘中输入一个整数a,
    如果该整数a为奇数, 且与这10个整数中的任一个数相同,则删掉与a相同的 这个数,并将剩下的9个数按升序排序输出;
    若a为偶数, 且与这10个数都不同,则加入a,并将这11个数降序排 序输出;
    否则,则将这10个数奇数在前,偶数在后, 降序排列输出。
    例如,10个数分别为6,89,34,12, 0,-8,78,15,9,3.
    若a为9,则输出为:-8,0,3, 6,12,15,34,78,89.
    若a为2,则输出为:89,78, 34,15,12,9,6,3,2,0,-8.
    若a为7或者12,则 输出为:89,15,9,3,78,34,12,6,0,-8.
    要求:使用函数解决本题,至少编写以下几个函数,
    1、升序排序函数void sort(int a[], int n);
    2、查找函数int find(int a[],int n,int value)—-在大小为n的a数组中查找值为value的元素,找到就返回元素的下标,找不到,就返回-1;
    3、输出函数display(int a[], int n)—逐个输出数组a的元素;
    4、反转数组函数void reverse(int a[], int n)—-将数组逆序。

    输入

    测试数据的组数n
    第一组测试数据的10个整数
    第一组的整数a
    第二组测试数据的10个整数
    第二组的整数a
    ……
    第n组测试数据的10个整数
    第n组的整数a

    输出

    第一组数据排序输出
    第二组数据排序输出
    …….
    第n组数据排序输出

    样例输入

    3
    6 89 34 12 0 -8 78 15 9 3
    9
    6 89 34 12 0 -8 78 15 9 3
    2
    6 89 34 12 0 -8 78 15 9 3
    7

    样例输出

    -8 0 3 6 12 15 34 78 89
    89 78 34 15 12 9 6 3 2 0 -8
    89 15 9 3 78 34 12 6 0 -8

    提示

    解决方案

    #include <stdio.h>
    
    #define FAILED_FIND_IN_ARRAY -1
    
    struct Array {
        int data[16];
        int size;
    };
    
    void scanToArray(struct Array *array);
    int findInArray(struct Array *array, int data);
    void sortArray(struct Array *array);
    void reverseArray(struct Array *array);
    void sortArrayInOddAndEven(struct Array *array);
    void printArray(struct Array *array);
    
    int main() {
        int ctrl;
        scanf("%d", &ctrl);
    
        while (ctrl--) {
            struct Array array = {};
            scanToArray(&array);
            int number;
            scanf("%d", &number);
            if (number % 2 != 0 && findInArray(&array, number) != FAILED_FIND_IN_ARRAY) {
                array.size -= 1;
                for (int i = findInArray(&array, number); i < array.size; ++i) {
                    array.data[i] = array.data[i + 1];
                }
                sortArray(&array);
            } else if (number % 2 == 0 && findInArray(&array, number) == FAILED_FIND_IN_ARRAY) {
                array.data[array.size] = number;
                array.size += 1;
                sortArray(&array);
                reverseArray(&array);
            } else {
                sortArrayInOddAndEven(&array);
            }
            printArray(&array);
        }
    
        return 0;
    }
    
    void scanToArray(struct Array *array) {
        array->size = 10;
        for (int i = 0; i < array->size; ++i) {
            scanf("%d", &array->data[i]);
        }
    }
    
    int findInArray(struct Array *array, int data) {
        for (int i = 0; i < array->size; ++i) {
            if (array->data[i] == data) {
                return i;
            }
        }
        return -1;
    }
    
    void sortArray(struct Array *array) {
        for (int i1 = 0; i1 < array->size - 1; ++i1) {
            for (int i2 = 0; i2 < array->size - 1 - i1; ++i2) {
                if (array->data[i2] > array->data[i2 + 1]) {
                    int data = array->data[i2];
                    array->data[i2] = array->data[i2 + 1];
                    array->data[i2 + 1] = data;
                }
            }
        }
    }
    
    void reverseArray(struct Array *array) {
        for (int i = 0; i < array->size / 2; ++i) {
            int data = array->data[i];
            array->data[i] = array->data[array->size - 1 - i];
            array->data[array->size - 1 - i] = data;
        }
    }
    
    void sortArrayInOddAndEven(struct Array *array) {
        struct Array odd = {}, even = {};
        for (int i = 0; i < array->size; ++i) {
            if (array->data[i] % 2 == 0) {
                even.data[even.size] = array->data[i];
                even.size += 1;
            } else {
                odd.data[odd.size] = array->data[i];
                odd.size += 1;
            }
        }
        sortArray(&odd);
        reverseArray(&odd);
        sortArray(&even);
        reverseArray(&even);
        for (int i = 0; i < odd.size; ++i) {
            array->data[i] = odd.data[i];
        }
        for (int i = 0; i < even.size; ++i) {
            array->data[i + odd.size] = even.data[i];
        }
    }
    
    void printArray(struct Array *array) {
        printf("%d", array->data[0]);
        for (int i = 1; i < array->size; ++i) {
            printf(" %d", array->data[i]);
        }
        printf("\n");
    }
    
  • 计算字符串的长度

    时间限制: 1 Sec 内存限制: 128 MB

    题目描述

    计算字符串S的长度,功能与strlen函数相同,但不能调用库函数strlen,否则不给分。输入的字符串不包含空格。

    输入

    输入测试组数t
    对于每组测试,输入字符串S(长度<=30)

    输出

    对于每组测试,输出S的长度

    样例输入

    1
    hehe
    

    样例输出

    4
    

    提示

    解决方案

    #include <iostream>
    
    int main() {
        int ctrl;
        std::cin >> ctrl;
        while (ctrl--) {
            char str[64] = {};
            std::cin >> str;
            int length = 0;
            while (str[++length] != '\0');
            std::cout << length << std::endl;
        }
    
        return 0;
    }
    

  • 单词统计

    时间限制: 1 Sec 内存限制: 128 MB

    题目描述

    编写一个程序,根据单词的出现频率降序打印出所输入的的各个单词。每个单词前标有它的计数值。

    输入

    各个单词,输入0则表示单词结束

    输出

    降序打印单词出现的频率和单词。单词频度相同,按出现顺序输出。

    样例输入

    bad
    good
    bad
    cute
    how
    good
    good
    0
    

    样例输出

    3 good
    2 bad
    1 cute
    1 how
    

    提示

    解决方案

    #include <iostream>
    #include <string>
    #include <vector>
    #include <algorithm>
    
    struct Pair {
        std::string string;
        int count;
        Pair(std::string &string, int count) : string(string), count(count) {}
    };
    bool operator==(Pair &pair, const std::string &string) {
        return pair.string == string;
    }
    bool operator<(const Pair &lhs, const Pair &rhs) {
        return lhs.count > rhs.count; // NG
    }
    
    int main() {
        std::vector<Pair> vector;
        std::string string;
        std::cin >> string;
        while (string != "0") {
            std::vector<Pair>::iterator it = std::find(vector.begin(), vector.end(), string);
            if (it != vector.end()) {
                it->count += 1;
            } else {
                vector.push_back(Pair(string, 1));
            }
            std::cin >> string;
        }
        std::sort(vector.begin(), vector.end());
        for (int i = 0; i < vector.size(); ++i) {
            std::cout << vector[i].count << ' ' << vector[i].string << std::endl;
        }
    
        return 0;
    }
    
  • 安卓通过 adb 将 TF(SD)卡用作内置存储

    手上有个 360 N6,平时当备用机,存点音乐视频什么的,存储空间不太够,于是乎买了张 TF 卡插上。(其实应该去看看紫光的超级 SIM 卡能不能用的,深圳联通公众号上也发可以参加预存话费赠卡的活动了)

    我的第一部智能手机买的是黑莓 Priv,插卡之后会提示格式化成外置的便携式存储(可以拔出来在不同设备,比如电脑上交换数据)还是内置存储(不能用在其它机器上),并且使用非常正常。

    好了问题来了,N6 插卡之后只能格式化成外置存储(?),这就很蛋疼,插卡的意义似乎就不大。后面发现其实可以用 adb 开启,虽然好像还是有点问题。

    But how?

    可以用 sm 来做到。

    首先连续多次点按设置->系统->关于手机->版本号,打开开发者选项,然后在开发者选项中打开 USB 调试。此时可以把手机连接到电脑上了。

    我正在使用 Android Studio,安装过 Android SDK,可以直接在 C:\Users\domain\AppData\Local\Android\Sdk\platform-tools 中找到 adb 工具。没有也没关系,从 SDK平台工具版本说明 | Android 开发者 | Android Developers 可以下载到独立的工具包。

    已经有了 platform-tools 之后,进入该目录,按住 Shift 再点击鼠标右键可以在该目录打开 PowerShell。此时运行:

    PS C:\Users\domain\AppData\Local\Android\Sdk\platform-tools> .\adb.exe devices
    List of devices attached
    * daemon not running; starting now at tcp:5037
    * daemon started successfully
    1f95707d        unauthorized

    显示未授权,此时手机上应该会弹窗是否允许电脑进行调试(以及一个密钥),允许后再次执行:

    PS C:\Users\domain\AppData\Local\Android\Sdk\platform-tools> .\adb.exe devices
    List of devices attached
    1f95707d        device

    此时可以:

    PS C:\Users\domain\AppData\Local\Android\Sdk\platform-tools> .\adb.exe shell
    QK1707:/ $

    有了手机的 Shell 了,尝试 sm 工具查看存储:

    QK1707:/ $ sm list-disks
    disk:179,64

    如果手机允许:

    QK1707:/ $ sm has-adoptable
    true

    反之则可能需要尝试 sm set-force-adoptable true。接下来 就可以:

    QK1707:/ $ sm partition disk:179,64 private

    来将存储卡格式化为内置存储。如果执行:

    QK1707:/ $ sm partition disk:179,64 mixed 30

    可以将部分空间格式化为内置存储,另一部分(30%)作为便携式存储。

    此时可以在设置中看到存储卡已经被设置为内置存储了。发现容量显示有问题,而且迁移也有点问题。网友分享格机后,安装应用不要打开马上迁移就没有问题。决定这几天格机再试一下。

    引用:
    android – How to turn a portable SD card into internal storage via ADB command? – Stack Overflow
    透過ADB方式開啟與配置Adoptable Storage空間(免root) @ 老梁’s blog :: 隨意窩 Xuite日誌
    360N7Lite免root安装应用到内存卡的方法及其它玩机教程-更新自动安装到内存卡_360社区

  • PowerShell Get-FileHash

    Get-FileHash
       [-Path] <String[]>
       [[-Algorithm] <String>]
       [<CommonParameters>]
    PS D:\Downloads> Get-FileHash .\cn_windows_10_enterprise_ltsc_2019_x64_dvd_9c09ff24.iso -Algorithm SHA1 | Format-List   
    
    Algorithm : SHA1
    Hash      : 24B59706D5EDED392423936C82BA5A83596B50CC
    Path      : D:\Downloads\cn_windows_10_enterprise_ltsc_2019_x64_dvd_9c09ff24.iso
    

    支持的算法:
    SHA1, SHA256, SHA384, SHA512, MD5。

    引用:
    Get-FileHash