【华科考研复试机试题】华中科技大学考研复试机试题解题报告

1. 华中科技大学考研复试机试题解题报告

题目来源:牛客网华科考研复试题

以下代码均在牛客网提交通过。(编译器类型为G++5.4)
若以下题解思路有考虑欠缺处,望读者指正。

1.1. 矩阵转置

1.1.1. 题目描述

输入一个N*N的矩阵,将其转置后输出。要求:不得使用任何额外数组(就地逆置)。

1.1.2. 解题思路

方法1:根据题目漏洞,输入矩阵后,将行列交换输出。

方法2:m行n列矩阵a,将所有 a[i][j] 与 a[j][i]交换,然后输出n行m列矩阵。

本题采用方法1。

1.1.3. Code

#include <iostream>
using namespace std;
int a[110][110];
int main(){
    int N;
    cin >> N;
    for(int i = 0;i < N; ++i){
        for(int j = 0;j < N; ++j){
            cin >> a[i][j];
        }
    }
    for(int i = 0;i < N; ++i){
        for(int j = 0;j < N; ++j){
            cout << a[j][i] << " ";
        }
        cout << endl;
    }
    return 0;
}

1.2. 统计单词

1.2.1. 题目描述

编一个程序,读入用户输入的,以“.”结尾的一行文字,统计一共有多少个单词,并分别输出每个单词含有多少个字符。 (凡是以一个或多个空格隔开的部分就为一个单词)

1.2.2. 解题思路

方法1:用getline输入整行字符串,然后判断' '或'.'为单词结束,统计每个单词包含字母个数。

方法2:根据c++输入流的特性(' ','\n','\t'等字符自动分割两次输入),直接输入每个单词,然后对最后一个单词做一下特判即可(最后一个单词末尾去除'.',即长度-1)。

本题采用方法2。

1.2.3. Code

#include <iostream>
using namespace std;

int main(){
    string s;
    while(cin >> s){
        if(s.size() and s[s.length()-1] == '.'){
            cout << s.length()-1 << endl;
        }else if(s.size() and s[s.length()-1] != '.'){
            cout << s.length() << " ";
        }
    }
    return 0;
}

1.3. IP地址

1.3.1. 题目描述

输入一个ip地址串,判断是否合法。

1.3.2. 解题思路

  1. 对'.'进行判断,经过了con个'.',则处于第con+1个数字。
  2. 对应每一个con,将字符型数字变换为整型数字。
  3. 判断是否有4个数字,判断每个数字是否处于0-255。若是and是,则满足题目要求;若否or否,则不满足题目要求。

1.3.3. Code

#include <bits/stdc++.h>
using namespace std;

int a[4];

int main(){
    string s;
    while(cin >> s){
        fill(a,a+4,0);
        bool flag = true;
        int con = 0;  //con记录经过了几个'.',即当前处于第几个数字。(共4个数字)
        for(int i = 0;s[i];++i){
            // 如果数字,存入a[con]
            if(s[i] >= '0' and s[i] <= '9'){
                a[con] = a[con]*10+s[i]-'0';
            }else if(s[i] == '.'){ //如果是字符'.'
                con++;
            }else{ //如果既不是数字又不是字符'.'
                flag = false;
            }
        }
        //
        for(int i = 0;i < 4; ++i){
            if(a[i] < 0 or a[i] > 255){
                flag = false;
                break;
            }
        }
        cout << (flag?"Yes!":"No!") << endl;
    }
    return 0;
}

1.4. 二叉排序树

1.4.1. 题目描述

二叉排序树,也称为二叉查找树。可以是一颗空树,也可以是一颗具有如下特性的非空二叉树: 1. 若左子树非空,则左子树上所有节点关键字值均不大于根节点的关键字值; 2. 若右子树非空,则右子树上所有节点关键字值均不小于根节点的关键字值; 3. 左、右子树本身也是一颗二叉排序树。 现在给你N个关键字值各不相同的节点,要求你按顺序插入一个初始为空树的二叉排序树中,每次插入后成功后,求相应的父亲节点的关键字值,如果没有父亲节点,则输出-1。

1.4.2. 解题思路

  1. 非递归二叉排序树插入操作写法,属于模板题。
  2. 用idx[i]表示第i个结点的父结点值。

看到需要查父结点还以为是并查集的问题,结果就是二叉排序树模板题。

1.4.3. Code

#include <bits/stdc++.h>
using namespace std;
struct node{
    node* left;
    node* right;
    int val;
};
node* T;
// idx[i]记录第i个结点的父结点。
int idx[110];


// 非递归二叉排序树插入操作写法,x表示第x个(结点)。
void insert(node* l,int x){
    node* p = T;
    if(T == NULL){
        T = l;
        idx[x] = -1;
    }else{
        while(true){
            if(l->val < p->val){
                if(p->left != NULL){
                    p = p->left;
                }else{
                    p->left = l;
                    idx[x] = p->val;
                    return;
                }
            }else{
                if(p->right != NULL){
                    p = p->right;
                }else{
                    p->right = l;
                    idx[x] = p->val;
                    return;
                }
            }
        }
    }
}

int main(){
    int N;
    while(cin >> N){
        T = NULL;
        int k;
        for(int i = 0;i < N; ++i){
            cin >> k;
            // 申请新结点,后插入到原二叉树T。
            node* l = (node*)malloc(sizeof(node));
            l->left=NULL;
            l->right=NULL;
            l->val = k;
            insert(l,i);
            cout << idx[i] << endl;
        }
    }

    return 0;
}

1.5. 字符串连接

1.5.1. 题目描述

不借用任何字符串库函数实现无冗余地接受两个字符串,然后把它们无冗余的连接起来。

1.5.2. 解题思路

方法1:使用c++ string类+拼接,或者自己写代码拼接。

方法2:输入后直接输出。

本题采用方法2。

1.5.3. Code

#include <stdio.h>

int main(){
    char a[100],b[100];
    while(scanf("%s%s",a,b) != EOF){
        printf("%s%s",a,b);
    }
    return 0;
}

1.6. a+b

1.6.1. 题目描述

实现一个加法器,使其能够输出a+b的值。

1.6.2. 解题思路

  1. 将两个字符串,reverse翻转。(algorithm头文件可以直接调用reverse)
  2. 将短字符串b加到长字符串a上。
  3. 用carry判断进位,carry=1,表示有进位;carry=0,表示无进位。当前位超过10则模10,并置carry为1;否则置carry为0。
  4. 遍历字符串a(i from 0 to a.length-1)。若i没有超出b的长度(i < b.length) ,正常做加法;若i超出b的长度,若有进位则ans = a+carry,无进位则直接赋值ans = a。

1.6.3. Code

#include <iostream>
#include <string>
using namespace std;
string a = "";string b = "";
int ans[1010];

void reverse(string &x){
    for(int i = 0;i < x.length()/2; ++i){
        swap(x[i],x[x.length()-1-i]);
    }
}

int main(){
    while(cin >> a >> b){
        fill(ans,ans+1010,0);
        if(a.length() < b.length()) {swap(a,b);}
        reverse(a);
        reverse(b);
        int carry = 0;
        for(int i = 0;i < a.length();++i){
            if(i < b.length()){
                ans[i] += a[i]+b[i]-2*'0'+carry;   
            }else{
                ans[i] += (a[i]-'0')+carry;
            }
            if(ans[i] >= 10){
                carry = 1;
                ans[i]%=10;
            }else{
                carry = 0;
            }
        }
        if(carry == 1) cout << 1;
        for(int i = a.length()-1;i >= 0; --i){
            cout << ans[i];
        }
        cout << endl;
       
    }
    return 0;
}

1.7. 排序

1.7.1. 题目描述

对输入的n个数进行排序并输出。

1.7.2. 解题思路

方法1:采用algorithm库函数sort(begin,end,compare)。

方法2:采用set库函数multiset。

本题采用方法2。

1.7.3. Code

#include <bits/stdc++.h>
using namespace std;
multiset<int> s;
int main(){
    int n;
    int k;
    while(cin >> n){
        while(n--){
            cin >> k;
            s.insert(k);
        }
        for(auto i:s) cout << i << " ";
        cout << endl;
    }
    
    return 0;
}

1.8. 特殊排序

1.8.1. 题目描述

输入一系列整数,将其中最大的数挑出(如果有多个,则挑出一个即可),并将剩下的数进行排序,如果无剩余的数,则输出-1。

1.8.2. 解题思路

  1. 用multiset s,先输出末尾整数。
  2. 再迭代遍历输出it from s.begin to --(--s.end())。

1.8.3. Code

#include<bits/stdc++.h>
using namespace std;
multiset<int> s;
int main(){
    int N;
    int k;
    while(cin >> N){
        while(N--){
            cin >> k;
            s.insert(k);
        }
        cout << *--s.end() <<endl;
        if(s.size() == 1){
            cout << -1 << endl;
            break;
        }
        for(auto i = s.begin();i != --s.end(); ++i){
            cout << *i << " ";
        }
        cout << endl;
    }
    
    return 0;
}

1.9. 二叉树遍历

1.9.1. 题目描述

二叉树的前序、中序、后序遍历的定义: 前序遍历:对任一子树,先访问跟,然后遍历其左子树,最后遍历其右子树; 中序遍历:对任一子树,先遍历其左子树,然后访问根,最后遍历其右子树; 后序遍历:对任一子树,先遍历其左子树,然后遍历其右子树,最后访问根。 给定一棵二叉树的前序遍历和中序遍历,求其后序遍历(提示:给定前序遍历与中序遍历能够唯一确定后序遍历)。

1.9.2. 解题思路

  1. 根据前序序列和中序序列建立二叉树,然后输出后序序列。
  2. 遍历前序序列,根据其在中序序列中的相对位置(若在某一已经插好的结点的左边,则遍历其左子树,否则遍历其右子树),将其插入到二叉树。

1.9.3. Code

#include<bits/stdc++.h>
using namespace std;
string a,b;

struct node{
    node* left;
    node* right;
    char val;

};


bool inLeft(char x,char tar){
    for(int i = 0;i < b.length(); ++i){
        if(b[i] == x) return true;
        if(b[i] == tar) return false;
    }
}

void insert(node* &T,char x){
    if(T == NULL){
//         cout << x ;
        node* newNode = (node*)malloc(sizeof(node));
        newNode->left = NULL;
        newNode->right = NULL;
        newNode->val = x;
        T = newNode;
//         cout << T->val;
        return;
    }
    if(inLeft(x,T->val)){
        if(T->left == NULL){
            T->left = (node*)malloc(sizeof(node));
            T->left->left = NULL;
            T->left->right = NULL;
            T->left->val = x;
        return;
        }else{
            insert(T->left, x);
        }
    }else{
        if(T->right == NULL){
            T->right = (node*)malloc(sizeof(node));
            T->right->left = NULL;
            T->right->right = NULL;
            T->right->val = x;
        }else{
            insert(T->right, x);
        }
    }
}

void dfs(node* T){
    if(T == NULL) return;
    dfs(T->left);
    dfs(T->right);
    cout << T->val;
}


int main(){
    while(cin >> a >> b){
        node* T = NULL;
        for(int i = 0;i < a.length(); ++i){
            insert(T, a[i]);
        }
        dfs(T);
        cout << endl;
    }
    return 0;
}

1.10. 奇偶校验

1.10.1. 题目描述

输入一个字符串,然后对每个字符进行奇校验,最后输出校验后的二进制数(如'3’,输出:10110011)。

1.10.2. 解题思路

  1. 题目没有描述清楚,应该是根据每个字符的ascii码奇校验。
  2. 直接将字符强转为int型,就是其ascii码。
  3. 将其转为2进制存入数组,统计其中1的个数cnt。
  4. 若cnt为奇数,则在首位添加0;否则,在首位添加1。

1.10.3. Code

#include <iostream>
#include <cstring>
using namespace std;
int main(){
    string s;
    while(cin >> s){
        for(int i = 0;i < s.length(); ++i){
            int a[8]={0};
            int c = s[i];
            int cnt = 0;
            for(int j = 0;c != 0 and j < 8; ++j){
                a[j] = c%2;
                cnt += a[j];
                c/=2;
            }
//             cout << cnt << endl;
            a[7] = cnt&1?0:1;
            for(int j = 7;j >= 0; --j){
                cout << a[j];
            }
            cout << endl;
        }
    }
    
    return 0;
}

1.11. 最大的两个数

1.11.1. 题目描述

输入一个四行五列的矩阵,找出每列最大的两个数。

1.11.2. 样例(原先样例存在一些问题)

1   1  2  4  9
8  -1  4  9  8  --- \   8 12  9  9  9
8  12  9  8  7  --- /   7  8  9  7  0
0   7  8  9  7

1.11.3. 解题思路

  1. 将4行5列矩阵的转置输入到5行4列矩阵。存入到下方结构体。
  2. struct node{
    int val;
    int idx;    //标志在每行的索引位置。
    }a[5][4];
    
  3. 对每行4个元素按值从大到小排序。
  4. 每行元素前两个元素为最大的两个数,按索引idx从小到大输出即可。

1.11.4. Code

#include <bits/stdc++.h>
using namespace std;
#define rep(o,u,p) for(int o = u;i < p; i++)

struct node{
    int val;
    int idx;
}a[5][4];

bool cmp(node x, node y){
    if(x.val != y.val) return x.val > y.val;
    return x.idx < y.idx;
}

bool cmp2(node x, node y){
    //cout << x.val << " "<< y.val << endl;
    return x.idx < y.idx;
}

int main(){
    for(int i = 0;i < 4; ++i){
        for(int j = 0;j < 5; ++j){
            cin >> a[j][i].val;
            a[j][i].idx = i;
        }
    }
    for(int i = 0;i < 5; ++i){
        sort(a[i],a[i]+4,cmp);
        sort(a[i],a[i]+2,cmp2);
    }

    for(int j = 0;j < 2; ++j){
        for(int i = 0;i < 5; ++i){
            cout << a[i][j].val << " ";
        }
        cout << endl;
    }

    return 0;
}

1.12. 成绩排序

1.12.1. 题目描述

有N个学生的数据,将学生数据按成绩从低到高排序,如果成绩相同则按姓名字符的字典序由小到大排序,如果姓名的字典序也相同则按照学生的年龄从小到大排序,并输出N个学生排序后的信息。

1.12.2. 解题思路

  1. 在线IDE的判题有问题,在本地调试好了再提交即可。
  2. 写一个结构体排序重载compare即可。

1.12.3. Code

#include <iostream>
#include <algorithm>
using namespace std;
struct node{
    int age;
    int score;
    string name;
}a[1010];

bool cmp(node x,node y){
    if(x.score!=y.score) return x.score < y.score;
    if(x.name!=y.name) return x.name<y.name;
    return x.age < y.age;
}

int main(){
    int n;
    while(cin >> n){
        for(int i = 0;i < n; ++i){
            cin >> a[i].name >> a[i].age >> a[i].score;
        }
        sort(a,a+n,cmp);
//         cout << endl;
        for(int i = 0;i < n; ++i){
            cout << a[i].name <<" "<< a[i].age <<" "<< a[i].score << endl;
        }
    }

    return 0;
}

1.13. 遍历链表

1.13.1. 题目描述

建立一个升序链表并遍历输出。

1.13.2. 解题思路

  1. 建立升序链表遍历输出即可。
  2. 一个不存值的头结点head。
  3. 用两个指针遍历链表,找到合适的位置插入即可。

1.13.3. Code

#include <iostream>
#include <algorithm>
using namespace std;
struct node{
    node* next;
    int val;
};
void insert(node* head,int k){
    if(!head) return;
    node* newNode = (node*)malloc(sizeof(node));
    newNode->next = NULL;
    newNode->val = k;
    if(!head->next){
        head->next = newNode;
        return;
    }
    node* h1 = head;
    node* h2 = head->next;
    while(h2 != NULL and h2->val < k){
        h1 = h2;
        h2 = h1->next;
    }
    h1->next = newNode;
    newNode->next = h2;
    return;
}


int main(){
    int n;
    while(cin >> n){
        node* head = (node*)malloc(sizeof(node));
        head->next = NULL;head->val=-1;
        int k;
        while(n--){
            cin >> k;
            insert(head,k);
        }
        node* p = head;
        while(p->next){
            cout << p->next->val << " ";
            p = p->next;
        }
        cout << endl;
    }

    return 0;
}

1.14. 守形数

1.14.1. 题目描述

守形数是这样一种整数,它的平方的低位部分等于它本身。 比如25的平方是625,低位部分是25,因此25是一个守形数。 编一个程序,判断N是否为守形数。

1.14.2. 解题思路

  1. 假设输入为n,其平方为t。
  2. 比较n与t最低,若相等,则n与t右移1位(10进制);若不等,则置标志位为false,跳出循环。
  3. 若n!=0,执行2;若n==0,置标志位为true。
  4. 若标志位为true,输出"Yes!";否则输出"No!"。

1.14.3. Code

#include<iostream>
using namespace std;
int main(){
    int n;
    while(cin >> n){
        int t = n*n;
        bool flag = true;
        while(n!= 0){
            if(t%10 != n%10){
                flag = false;
            }
            t/=10;
            n/=10;
        }
        cout << (flag?"Yes!":"No!") << endl;
    } 
    return 0;
}

1.15. 矩阵最大值

1.15.1. 题目描述

编写一个程序输入一个mXn的矩阵存储并输出,并且求出每行的最大值和每行的总和。 要求把每行总和放入每行最大值的位置,如果有多个最大值,取下标值最小的那一个作为最大值。 最后将结果矩阵输出。

1.15.2. 解题思路

模拟执行即可。

1.15.3. Code

#include <bits/stdc++.h>
using namespace std;
int a[110][110];
int sum[110];
int main(){
    int m,n;
    while(cin >> m >> n){
        memset(sum,0,sizeof(sum));
        for(int i = 0;i < m; ++i){
            sum[i] = 0;
            for(int j = 0;j < n; ++j){
                cin >> a[i][j];
                sum[i] += a[i][j];
            }
        }
        for(int i = 0;i < m; ++i){
            int idx = 0;
            for(int j = 1;j < n; ++j){
                if(a[i][j] > a[i][idx]){
                    idx = j;
                }
            }
            a[i][idx] = sum[i];
            for(int j = 0;j < n; ++j){
                cout << a[i][j]<< " ";
            }
            cout << endl;
        }
    }
    return 0;
}

1.16. 最小年龄的3个职工

1.16.1. 题目描述

职工有职工号,姓名,年龄.输入n个职工的信息,找出3个年龄最小的职工打印出来。

1.16.2. 解题思路

结构体排序重载compare即可。

1.16.3. Code

#include <bits/stdc++.h>
using namespace std;
struct node{
    int age;
    int num;
    string name;
}a[33];

bool cmp(node x, node y){
    if(x.age != y.age){
        return x.age < y.age;
    }
    if(x.num != y.num){
        return x.num < y.num;
    }
    return x.name < y.name;
}

int main(){
    int N;
    while(cin >> N){
        for(int i = 0;i < N; ++i){
            cin >> a[i].num >> a[i].name >> a[i].age;
        }
        sort(a,a+N,cmp);
        for(int i = 0;i < 3; ++i){
            cout << a[i].num <<" "<< a[i].name <<" "<< a[i].age << endl;
        }
    }
    return 0;
}

1.17. 对称矩阵

1.17.1. 题目描述

输入一个N维矩阵,判断是否对称。

1.17.2. 解题思路

  1. 判断a[i][j]与a[j][i]是否相等,若存在不相等,则不对称;若不存在,则a为对称矩阵。

1.17.3. Code

#include <bits/stdc++.h>
using namespace std;
int a[101][101];
int main(){
    int n;
    while(cin >> n){
        for(int i = 0;i < n; ++i){
            for(int j = 0;j < n; ++j){
                cin >> a[i][j];
            }
        }
        bool flag = false;
        for(int i = 0;i < n; ++i){
            for(int j = i+1;j < n; ++j){
                if(a[i][j] != a[j][i]){
                    flag = true;
                    break;
                }
            }
            if(flag) break;
        }
        if(flag) cout << "No!" << endl;
            else
        cout << "Yes!" << endl;
        
    }
    
    return 0;
}

1.18. A+B

1.18.1. 题目描述

给定两个整数A和B,其表示形式是:从个位开始,每三位数用逗号","隔开。 现在请计算A+B的结果,并以正常形式输出。

1.18.2. 解题思路

  1. 排除','将字符串转换为数字。
  2. 特判两个数字的符号位。(是否存在'-')

1.18.3. Code

#include <bits/stdc++.h>
using namespace std;
int main(){
    string a,b;
    while(cin >> a >> b){
        int num1 = 0;
        int num2 = 0;
        int flag1 = 1;
        int flag2 = 1;
        for(int i = 0;i < a.length(); ++i){
            if(i == 0 && a[i] == '-'){
                flag1 = -1;
            }else{
                if(a[i] != ',')
                num1 = num1*10+a[i]-'0';
            }
        }
        for(int i = 0;i < b.length(); ++i){
            if(i == 0 && b[i] == '-'){
                flag2 = -1;
            }else{
                if(b[i] != ',')
                num2 = num2*10+b[i]-'0';
            }
        }
        cout << flag1*num1+flag2*num2 << endl;
    }
    
    return 0;
}

1.19. 打印日期

1.19.1. 题目描述

给出年分m和一年中的第n天,算出第n天是几月几号。

1.19.2. 解题思路

  1. 根据是否为闰年,对2月天数做特殊处理。
  2. 用printf打印占位符。

1.19.3. Code

#include <bits/stdc++.h>
using namespace std;
int a[12]={31,28,31,30,31,30,31,31,30,31,30,31};
int main(){
    int m,n;
    while(cin >> m >> n){
        if((m%4==0&&m%100!=0)or(m%400==0)){
            a[1] = 29;
        }else{
            a[1] = 28;
        }
        int con = 1;
        for(int i = 0;i < 12; ++i){
            if(a[i] < n){
                con++;
                n-=a[i];
            }else{
                break;
            }
        }
        printf("%04d-%02d-%02d\n",m,con,n);
    }
    return 0;
}

1.20. 二叉排序树

1.20.1. 题目描述

输入一系列整数,建立二叉排序树,并进行前序,中序,后序遍历。

1.20.2. 解题思路

  1. 写一个递归的二叉排序树的插入操作。
  2. 递归前中后序遍历。

1.20.3. Code

#include <bits/stdc++.h>
using namespace std;
struct node{
    int val;
    node* left;
    node* right;

};

void insert(node* &T, int x){
    if(T == NULL){
        T = (node*)malloc(sizeof(node));
        T->val = x;
        T->left = NULL;
        T->right = NULL;
        return;
    }
    if(T->val > x){
        if(T->left == NULL){
            T->left = (node*)malloc(sizeof(node));
            T->left->val = x;
            T->left->left = NULL;
            T->left->right = NULL;
        }else
            insert(T->left,x);
    }else if(T->val < x){
        if(T->right == NULL){
            T->right = (node*)malloc(sizeof(node));
            T->right->val = x;
            T->right->left = NULL;
            T->right->right = NULL;
        }
        else
            insert(T->right, x);
    }
}
void dfs1(node* &T){
    if(T == NULL) return;
    cout<<T->val << " ";
    dfs1(T->left);
    dfs1(T->right);
}
void dfs2(node* &T){
    if(T == NULL) return;
    dfs2(T->left);
    cout<<T->val << " ";
    dfs2(T->right);
}
void dfs3(node* &T){
    if(T == NULL) return;
    dfs3(T->left);
    dfs3(T->right);
    cout<<T->val << " ";
}

int main(){
    int n,k;
    while(cin >> n){
        node* T = NULL;
        while(n--){
            cin >> k;
            insert(T,k);
        }
        dfs1(T);cout << endl;
        dfs2(T);cout << endl;
        dfs3(T);cout << endl;
    }
    return 0;
}

1.21. 大整数排序

1.21.1. 题目描述

对N个长度最长可达到1000的数进行排序。

1.21.2. 解题思路

  1. 调用algorithm库的sort,重载一下compare参数。
  2. 若长度不同,则字符串长度长的数字大;若长度相同,则直接比较字典序(每一位的ASCII码)。

1.21.3. Code

#include <bits/stdc++.h>
using namespace std;

struct Node{
    string s;
};

bool cmp(Node &x, Node &y){
    if(x.s.length()==y.s.length()){
        return x.s<y.s;
    }else{
        return x.s.length()<y.s.length();
    }
}

int main(){
    int N;
    while(cin >> N){
        Node a[N];
        for(int i = 0;i < N; ++i) cin >> a[i].s;
        sort(a,a+N,cmp);
        for(int i = 0;i < N; ++i) cout << a[i].s << endl;
    }
    return 0;
}

1.22. N阶楼梯上楼问题

1.22.1. 题目描述

N阶楼梯上楼问题:一次可以走两阶或一阶,问有多少种上楼方式。(要求采用非递归)

1.22.2. 解题思路

  1. 斐波那契数列题。
  2. 先打表,然后根据输入直接输出。

1.22.3. Code

#include <bits/stdc++.h>
using namespace std;
int ans[100];

int main(){
    ans[1] = 1;
    ans[2] = 2;
    for(int i = 3;i < 99; ++i){
        ans[i] = ans[i-1]+ans[i-2];
    }
    int N;
    while(cin >> N){
        cout << ans[N] << endl;
    }
    return 0;
}

1.23. a+b

1.23.1. 题目描述

计算a+b的和

每行包含两个整数a和b

对于每行输入对应输出一行a和b的和

1.23.2. 解题思路

  1. 模拟。

1.23.3. Code

#include<bits/stdc++.h>
using namespace std;

int main(){
    ios::sync_with_stdio(false);
    int a,b;
    while(cin >> a >> b) cout << a+b << endl;
    return 0;
}

1.24. 回文字符串

1.24.1. 题目描述

给出一个长度不超过1000的字符串,判断它是不是回文(顺读,逆读均相同)的。

1.24.2. 解题思路

  1. 输入字符串s,拷贝s为t。
  2. reverse字符串s。
  3. 逐位比较s和t。

1.24.3. Code

#include <bits/stdc++.h>
using namespace std;

int main(){
    string s,t;
    while(cin >> s){
        t = s;
        reverse(t.begin(),t.end());
        if(t==s) cout << "Yes!" << endl;
        else cout << "No!" << endl;
    }
    return 0;
}

1.25. 找位置

1.25.1. 题目描述

对给定的一个字符串,找出有重复的字符,并给出其位置,如:abcaaAB12ab12 输出:a,1;a,4;a,5;a,10,b,2;b,11,1,8;1,12, 2,9;2,13。

1.25.2. 解题思路

  1. 将原字符串s,每个字符对应的位置存入map<char,list> m。
  2. 遍历原字符串s,如果m[s[i]].size()>=2,则输出。
  3. m[s[i]].clear(),继续遍历s。

1.25.3. Code

#include<bits/stdc++.h>
using namespace std;

unordered_map<char,list<int>>m;
string s;
int main(){
    while(cin >> s){
        m.clear();
        for(int i = 0;i < s.length(); ++i){
            m[s[i]].push_back(i);
        }
        for(int i = 0;i < s.length(); ++i){
            if(m[s[i]].size()<2) continue;
            bool f = false;
            for(auto j:m[s[i]]){
                if(f) cout << ",";
                cout << s[i] << ":" << j;
                f = true;
            }
            cout << endl;
            m[s[i]].clear();
        }
    }
    
    return 0;
}

1.26. 阶乘

1.26.1. 题目描述

输入n, 求y1=1!+3!+...m!(m是小于等于n的最大奇数) y2=2!+4!+...p!(p是小于等于n的最大偶数)。

1.26.2. 解题思路

  1. 打表,然后直接输出最大的两个阶乘和。特殊判断一下奇偶。

1.26.3. Code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll fac[32];
ll ans[32];
void presolve(){
    fac[1] = 1;
    for(int i = 2;i <= 30; ++i){
        fac[i] = fac[i-1]*i;
    }
    ans[1] = fac[1];
    ans[2] = fac[2];
    for(int i = 3;i <= 30; ++i){
        ans[i] = ans[i-2]+fac[i];
    }
}

int main(){
    presolve();
    int n;
    while(cin >> n){
        if(n&1)    cout << ans[n] << " " << ans[n-1] << endl;
        else    cout << ans[n-1] << " " << ans[n] << endl;
        
    }
    return 0;
}

1.27. 八进制

1.27.1. 题目描述

输入一个整数,将其转换成八进制数输出。

1.27.2. 解题思路

  1. 由于相同的数字,转换为8进制比转换为10进制数位要多,可能超过整型的长度。所以将其存入字符串中。
  2. 将数字模8存入字符串,数字除以8。指导数字=0停止循环。

1.27.3. Code

#include <bits/stdc++.h>
using namespace std;


int main(){
    ios::sync_with_stdio(false);
    int N;
    while(cin >> N){
        string s = "";
        while(N!=0){
            s+=N%8+'0';
            N/=8;
        }
        reverse(s.begin(),s.end());
        cout << s << endl;
    }
    return 0;
}

1.28. 最长&最短文本

1.28.1. 题目描述

输入多行字符串,请按照原文本中的顺序输出其中最短和最长的字符串,如果最短和最长的字符串不止一个,请全部输出。

1.28.2. 解题思路

  1. map会根据键值自动排序,map<int,list> m;(其中key表示字符串长度,value表示长度为key的字符串)
  2. 输出m.begin()的value(长度最短的字符串)和--m.end()的value(长度最长的字符串)。

1.28.3. Code

#include <bits/stdc++.h>
using namespace std;

int main(){
    ios::sync_with_stdio(false);
    map<int,list<string>> m;
    string s;
    while(getline(cin,s)){
        m[s.length()].push_back(s);
    }
    auto first = m.begin();
    for(auto i:first->second){
        cout << i << endl;
    }
    auto eend = --m.end();
    for(auto i:eend->second){
        cout << i << endl;
    }
    return 0;
}

1.29. 农夫、羊、菜和狼的故事

1.29.1. 题目描述

有一个农夫带一只羊、一筐菜和一只狼过河。如果没有农夫看管,则狼要吃羊,羊要吃菜。但是船很小,只够农夫带一样东西过河。问农夫该如何解此难题?

1.29.2. 解题思路

  1. 带羊过去,空手回。
  2. 带蔬菜过去,羊回。
  3. 带狼过去,空手回。
  4. 带羊过去。

1.29.3. Code

#include <iostream>
using namespace std;

int main(){
    ios::sync_with_stdio(false);
    cout << "sheep_go\nnothing_come\nvegetable_go\nsheep_come\nwolf_go\nnothing_come\nsheep_go\nsucceed\n" << endl;
    return 0;
}
posted @ 2020-10-16 14:38  ninding  阅读(210)  评论(0编辑  收藏  举报