兰州大学考研复试计算机专硕经验帖

距离兰大23年复试已经过了将近两个月,本人成功上岸23年兰大计算机专硕,在此写一些复试流程以及一些注意点,以供学弟学妹参考。

本人本科就读于江苏某211,毕业后参加了工作,后辞职参加23年考研,初试成绩一志愿中排30出头。今年一志愿上线好像是120人左右,加上调剂的二十多个人(具体不确定,应该差不多),所以竞争激烈,出成绩当天是75个拟录取计算机专硕,还有三四个士兵和少骨计划,听说后面补录了几个。而且今年学生学校都不弱,985/211/双一流占据了大多数,学校差不到哪里去,完全是看实力竞争。

复试报道

今年是4.1开始复试,前一天报道,到飞云楼交相关材料,到时候会贴出相应的考试座次、时间、教室信息。交完材料一定要看清楚第二天考试在哪,提前去教学楼踩点,免得第二天急急忙忙找不到教室。

复试计算机网络/英语听力测试

4.1正式开始复试,首先早上进行计算机网络和英语听力考试,这两门是在一个教室考,先是听力,应该是半小时时间,有填空和选择。说到听力,基础差的一定要重视,不要小看听力分数占比不大,本人就是英语听力极差,复试复习没有状态复习听力,考的一塌糊涂,拉低了总成绩。考完听力休息一会就是计算机网络,时长3小时,都是基础常规题,有选择,简答和大题,历年真题做一做,最重要的,把计算机网络的书好好过一遍,特别是书上的例题,要保证会做。选择题简单,但是要注意书上细节知识。大题和往年差不多。

复试上机考试

上机是在一号下午,考三道题,历时3小时,语言可选C/C++,Java,Python。本地写好后打包压缩提交。参考以往的题,今年专硕难度较低。对于科班学生来说,只要考前一两个月多练习编程,基本上没什么难度。今年第一题是给一个日期字符串,如"2023-06-01"判断是今年的第几天,需要注意月份天数影响;第二题是一个求海拔的题,具体有点忘了,也是很简单;第三题是判断灯的开关状态,开始状态是灭的(也可能是亮的,记不清了),来个学生拉一下,判断最后灯是亮还是灭。由于题目具体细节忘了,就不贴代码了,比之前的简单。

以下是历年机试题,如有错误请指出:

十进制转十二进制

问题:输入十进制转十二进制


#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
    cout << "输入一个十进制整数" << endl;
    int n;
    cin >> n;
    bool isMinus = false;
    if (n < 0)
    {
        isMinus = true;
        n *= -1;
    }
    string str = "";    
    while (n) 
    {
        int x = n % 12;
        if (x == 10)
            str += "A";
        else if (x == 11)
            str += "B";
        else
            str += x + '0';//任何数字加'0'都是这个数字的字符
        n /= 12; 
    }
    
    reverse(str.begin(), str.end());
    cout << "十二进制为:"; 
    if (isMinus)
        str = "-" + str;
    cout << str << endl;
    return 0;
}
public class Test {

    public static void main(String[] args) {
        System.out.println(convertToTwelveHex2(-28));
    }

    public static String convertToTwelveHex(int decimal) {
        boolean isNegative = false;

        if (decimal < 0) {
            isNegative = true;
            decimal = Math.abs(decimal);
        }

        String twelveHex = Integer.toString(decimal, 12).toUpperCase();

        if (isNegative) {
            twelveHex = "-" + twelveHex;
        }

        return twelveHex;
    }

    public static String convertToTwelveHex2(int decimal) {
        StringBuilder twelveHex = new StringBuilder();

        boolean isNegative = decimal < 0;
        decimal = Math.abs(decimal);

        while (decimal != 0) {
            int remainder = decimal % 12;
            twelveHex.insert(0, getHexDigit(remainder));
            decimal /= 12;
        }

        if (twelveHex.length() == 0) {
            twelveHex.append("0");
        }

        if (isNegative) {
            twelveHex.insert(0, "-");
        }

        return twelveHex.toString();
    }

    public static char getHexDigit(int digit) {
        if (digit < 10) {
            return (char) (digit + '0');
        } else {
            return (char) (digit - 10 + 'A');
        }
    }
}
  1. 十二进制转十进制

问题:输入十二进制转十进制


#include<iostream>
using namespace std;

int transWord(char s)
{
    if (s == 'a' || s == 'A')
        return 10;
    else if (s == 'b' || s == 'B')
        return 11;
    else
        return s - '0';
}

int main()
{
    string str12;
    cin >> str12;
    int size = str12.size();
    if (size == 0)
    {
        return 0;
    }
    bool isMinus = false;
    if (str12[0] == '-')
    {
        isMinus = true;
    }
    int data = 0;
    for (int i = isMinus ? 1 : 0; i < size; i++)
    {
        data = data * 12 + transWord(str12[i]);
    }
    data = isMinus ? -1 * data : data;
    cout << data;
}
    public static int convertToDecimal(String twelveHex) {
        boolean isNegative = false;
        int startIndex = 0;

        if (twelveHex.charAt(0) == '-') {
            isNegative = true;
            startIndex = 1;
        } else if (twelveHex.charAt(0) == '+') {
            startIndex = 1;
        }

        int decimal = 0;
        int power = 1;

        for (int i = twelveHex.length() - 1; i >= startIndex; i--) {
            char ch = twelveHex.charAt(i);
            int digit = getDecimalDigit(ch);
            decimal += digit * power;
            power *= 12;
        }

        if (isNegative) {
            decimal = -decimal;
        }

        return decimal;
    }

    public static int getDecimalDigit(char ch) {
        if (ch >= '0' && ch <= '9') {
            return ch - '0';
        } else if (ch >= 'A' && ch <= 'F') {
            return ch - 'A' + 10;
        } else if (ch >= 'a' && ch <= 'f') {
            return ch - 'a' + 10;
        } else {
            throw new IllegalArgumentException("Invalid twelveHex character: " + ch);
        }
    }
  1. 过滤重复字符串

问题:去掉一个字符串重复的字符


#include<iostream>
#include<set>

using namespace std;

int main()
{       
    string str;
    cin >> str;
    set<char> sets;
    
    for (int i = 0; i < str.size(); i++)
    {
        if (i == 0 || sets.count(str[i]) == 0)
        {
            sets.insert(str[i]);
            cout << str[i];
        }
    }

   return 0;
}
  1. 求最大公共子串

问题:求两个字符串的公共子串,解法很多这里采用二维数组来解


/**
如果两个字符串有公共子串,那么以这两个字符串为横纵坐标构成
一个二维数组,若相等则赋值左上角元素+1,否则为0,特殊第一行第一列
有相同只赋值1 ,例如,下面两个公共子串为abc
   b a b c d
 f 0 0 0 0 0 
 a 0 1 0 0 0
 a 0 1 0 0 0
 b 1 0 2 0 0
 c 0 0 0 3 0
 e 0 0 0 0 0
那么构成这样一个二维数组,存在多个公共子串的情况下,
我们只需要找到最大的元素max,并记录他的下标横坐标x,如
此例子中max = 3的横坐标 x = 3,利用 横向字符串的 substr(x - max + 1, max) 
可获得最长子串。同理如果记录纵坐标 y,需要用纵向字符串去获取公共子串。 
**/ 

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std; 
int main()
{
    string s1, s2;
    cin >> s1 >> s2;
    vector<vector<int>> vect;
    int size1 = s1.size();
    int size2 = s2.size();
    int max = 0;
    int x = 0;//最大值横坐标 
    for (int i = 0; i < size1; i++)
    {
        vector<int> temp;
        for (int j = 0;j < size2; j++)
        {
            if (s1[i] == s2[j])
            {
                if (i == 0 || j == 0)//第一行或第一列只能是1 
                {
                    max = 1; 
                    x = i;
                     temp.push_back(1);
                } 
                else //其他位置找到左上角的元素给他加一 
                {
                    int t = vect[i-1][j-1] + 1;//取左上角位置值+1 
                    if (t > max)//更新max同时记录坐标 
                    {
                        max = t;
                        x = i;
                    }
                    temp.push_back(t); 
                }    
            }
            else
            {
                temp.push_back(0);
            }
        }
        vect.push_back(temp);
    }
    
    if (!max)
    {
        cout << "不存在公共子串";
        return 0;
    }
    
    cout << s1.substr(x - max + 1, max);
     
    return 0;
}
  1. 求素数

问题:输入正整数n,求n以内素数


#include<iostream>
#include<cmath> 
using namespace std;
int main()
{
    int n;
    cin >> n;
    for (int i = 2;i < n;i++)
    {
        bool flag = true;
        for (int j = 2;j <= (int) sqrt(i);j++)
        {
            if (i % j == 0)
            {
                flag = false;
                break;
            }
        }
        if (flag)
        {
            cout << i << " ";
        }
    }
    return 0;
}
  1. 字符串转置

问题:给一个字符串句子中每个单词逆序

输入:to be or not to be

输出:ot eb ro ton ot eb


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

int main()
{
    vector<string> vect;
    string str;
    getline(cin, str);
    int size = str.size();
    
    for (int i = 0, p = 0; i < size;)
    {
        while (p < size && str[p] != ' ')
        {
            p++;
        }

        vect.push_back(str.substr(i, p - i));

        while (p < size && str[p] == ' ')
        {
            p++;
        }
        i = p;
    }
    
    str = "";
    for (auto i : vect)
    {
        reverse(i.begin(), i.end());
        str += i + " ";
    }
    str.pop_back();
    cout << str;
}
  1. 星号排版

问题:输入奇数输出星号


/**
这是个有规律的图形,上下关于中间一行对称,我们可以存储一半然后输出,另一半倒着输出
以n = 13 为例,上六行下六行对称,我们存储中间一行加下六行 
然后下面一半又是左右对称,很容易发现打印规律
如果整体下半部分看做矩形,左下方和右下方是个三角形空白部分
共同特征是左下三角i > j,右下三角j > n - i - 1; 
中间三角形,每个*号上面是空格,空格上面是* 
**/ 
#include<iostream>
#include<vector>
using namespace std;
int main()
{
    int n;
    cin >> n;
    if (n % 2 == 0)
    {
        cout << "请输入奇数!!!";
        return 0;
    }
        
    vector<vector<char>> vect;
    
    for (int i = 0; i < n / 2 + 1; i++)
    {
        vector<char> temp;
        
        for (int j = 0; j < n; j++)
        {
            if (i == 0)//最中间一行,偶数下标为*,奇数下标为空格 
            {
                if (j % 2 == 0)
                {
                    temp.push_back('*');
                
                }    
                else
                {
                    temp.push_back(' ');
                }                    
            }
            else//中间一行往下部分 
            {
                if (j < i || j > n - 1 - i)//左下和右下三角全为空格 
                {
                    temp.push_back(' ');
                
                }
                else//中间三角形,每个*号上面是空格,空格上面是* 
                {
                    if (vect[i-1][j] == ' ')
                    {
                        temp.push_back('*');
                        
                    }
                    else 
                    {
                        
                        temp.push_back(' ');
                    }        
                }
            }    
        }
        
        vect.push_back(temp);
    }
    
    //上半部分倒着打印 
    for (int i = n / 2; i > 0; i--)
    {
        for (int j = 0; j < n; j++)
        {
            cout << vect[i][j];
        }
        cout << endl;
    } 
     
    for (int i = 0; i <  n / 2 + 1; i++)
    {
        for (int j = 0;j < n; j++)
        {
            cout << vect[i][j];
        }
        cout << endl;
    } 
}
  1. 求三角形面积

问题:给你三个边,求面积,使用秦九韶公式


#include<iostream>
#include<cmath> 
using namespace std;
int main()
{
    int a, b, c;
    cin >> a >> b >> c;
    int p = (a + b + c) / 2;
    if (a + b > c && a + c > b && b + c > a)
    {
        cout << sqrt(p * (p - a) * (p - b) * (p - c));
    }
    else
    {
        cout << "边不合法";
    }
    return 0;
 } 
  1. 完数

问题:输出n以内完数

定义:一个数恰好等于除它本身以外的因子之和


#include<iostream>
#include<cmath>
using namespace std;
int main()
{
    int n;
    cin >> n;
    for (int i = 1; i < n; i++)
    {
        int sum = 0;
        for (int j = 1; j < i; j++)
        {
            if (i % j == 0)
            {
                sum += j;
            }
        }
        if (sum == i)
        {
            cout<<i<<" ";
        }
    }
    return 0;
}
  1. 约瑟夫环/猴子选大王

问题:n个人坐一圈,从k开始报数,报到m退出,直到全部出局,求出圈顺序

两个问题类似,解法很多,我给出一种


#include<iostream>
#include<vector>

using namespace std;

int main()
{
     int num;//输入人数
     int k;//开始报数编号
     int m;//报数到m退出 
     cin >> num >> m >> k;
     vector<pair<int, bool>> peoVec;//序号以及是否出局组成一对
     for (int i = 0 ; i < num; i++)
     {
         peoVec.push_back(pair<int, bool> (i + 1, false));
     }
     int count = 0;//计数器,到m退出
     int pCount = num;//退出人数
     for (int i = k - 1; pCount > 0; i++)
     {
         if (i == num)
        {
            i = 0;
        }
         if (!peoVec[i].second)
             count++;
         if (count == m)
         {
             peoVec[i].second = true;
             count = 0;
             pCount--;
             cout << peoVec[i].first << "号出局" << endl;
        }
        
     }
    
}
  1. 大数相加

问题:给出两个超出正常范围的十进制数进行求和

这道题使用字符串解其实有点问题,直接返回了字符串,如果判断结果要接收整数类型其实是有问题的


#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
    string num1, num2;
    cin >> num1 >> num2;
    int flag = 0;//进位
    string ans = "";//求和 
    for (int i = num1.size() - 1, j = num2.size() - 1; i >= 0 || j >= 0 || flag; i--, j--)
    {
        int sum = 0;
        if (i >= 0)
        {
            sum += num1[i] - '0';
        }
        
        if (j >= 0)
        {
            sum += num2[j] - '0';
        }
        
        sum += flag;
        flag = sum / 10;
        ans.push_back(sum % 10 + '0');//数字+'0'等于该数字的字符 
    }
    reverse(ans.begin(), ans.end());
    cout << ans;
    return 0; 
}
  1. 加和

问题:给定一个整数target,以及n个整数,求在这个整数序列中找到加和为target的所有组合


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

set<vector<int> > res;//最终结果集合,使用set的元素唯一性,排除重复组合

//curr目前求和,arr临时数组 
void backtracking(vector<int> &num, int target, int curr, int begin, 
vector<int> &arr) 
{
    if (curr >= target) 
    {
        if (curr == target) // 如果当前值与目标值相等
            res.insert(arr);          
        return;
    }
    
    for (int i = begin; i < num.size(); i ++) // 从begin位置开始遍历取值
    { 
        arr.push_back(num[i]); // 加入到数组中
        
        backtracking(num, target, curr + num[i], i + 1, arr); // 从下一位置开始递归
        
        arr.pop_back(); // 恢复数组
    }
    
    return;
}

vector<vector<int> > combinationSum(vector<int> &num, int target) 
{
        
    vector<int> arr;
    
    backtracking(num, target, 0, 0, arr);
    
    return vector<vector<int>>(res.begin(), res.end());
}

int main()
{
    vector<int> num = {1,2,3,4,5};
    vector<vector<int>> rv = combinationSum(num, 5); 
    for (auto v : rv)
    {
        for (auto i : v)
        {
            cout << i << " ";
        }
        cout << endl;
    }
}

  1. 字符串删除

问题:输入两个字符串s1和s2,在s1中删除含有s2的子串,返回删除子串个数num以及最后剩下的字符


#include<iostream>
using namespace std; 
int main()
{
    string str1, str2;;
    cin >> str1 >> str2;
    int size1 = str1.size();
    int size2 = str2.size();
    if (size1 < size2)
        return 0;
    bool flag = true;
    int num = 0;
    while (flag)
    {
        int index = str1.find(str2);
        if (index < 0)
        {
            flag = false;
        }
        else
        {
            str1.erase(index, size2);
            num++;
        }
    }
    cout << str1 << endl << num;
    return 0;
}
  1. 字符串压缩

问题:输入一个字符串str,对输入字符进行压缩,如

输入:aaabbcddddde

输出:3a2bc5de


#include<iostream>
using namespace std;
int main()
{
    string str;
    cin >> str;
    int size = str.size();
    string ans = "";
    for (int i = 0; i < size;)
    {
        int count = 0;
        char c = str[i];
        while (i < size && str[i] == c)
        {
            count++;
            i++;
        }
        if (count > 1)
        {
            ans.push_back(count + '0');
        }
        ans += c;
    }
    cout << ans;
    return 0;
}
  1. 平方对称数

问题:如11平方为121,则11是平方对称数,输出yes,否则no,输出256以内的数


#include<iostream>
using namespace std;
int main()
{
    for (int i = 0; i < 256; i++)
    {
        string str = to_string(i * i);
        int size = str.size();
        bool flag = true;
        for (int j = 0; j <= size / 2; j++)
        {
            if (str[j] != str[size - j -1])
            {
                flag = false;
                break;
            } 
        }
        if (flag)
            cout << i <<endl;
    }
    return 0; 
}
  1. 表达式求值/设计计算器

问题:给一个多项式如3*4-5,求值


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

/* stackOp(栈内) 的优先级是否高于(扫描到的) strOp */
bool priority(char stackOp, char strOp)
{
    if (strOp == '+' || strOp == '-')
        return true;
    else if (strOp == '*' || strOp == '/')
        return (stackOp == '*') || (stackOp == '/');
    return false;
}

void calcData(stack<double>& numStack,stack<int>& opStack)
{
    double result;
    
    double rhs = numStack.top();
    numStack.pop();//右操作数
    
    double lhs = numStack.top();
    numStack.pop();//左操作数
    
    switch(opStack.top())
    {
        case '+':result = lhs + rhs; break;
        case '-':result = lhs - rhs; break;
        case '*':result = lhs * rhs; break;
        case '/':result = lhs / rhs; break; 
        default: ;
    }
    
    opStack.pop();         //计算完成后,该运算符要弹栈
    numStack.push(result);   //将新计算出来的结果入栈
    return;
}

/* 将字符串转化为数字 */
double getDigit(int& index, int size, string s)
{
    double digit = 0;
    for(; index < size && isdigit(s[index]); index++)
    {
        digit = 10 * digit + (s[index] - '0');
    }
    return digit;     
}

double calculate(string s) 
{
    stack<double> numStack;  //存储表达式中的数值
    stack<int> opStack; //存储表达式中的运算符
    
    int index = 0;
    int size = s.size();
    
    while(index < size)
    {
        if(isdigit(s[index]))
        {
            numStack.push(getDigit(index, size, s));
        } 
        else 
        {
            /* 取运算符 */
            while(opStack.size() && priority(opStack.top(), s[index]))
            {
                calcData(numStack, opStack);
            }
            opStack.push(s[index]);
            index++;    
        }    
    }
    
    /* 保存最后一次运算 */
    while(opStack.size())
    {
        calcData(numStack, opStack);
    }
       
    return numStack.top();
}

int main()
{
    //全当做正确的表达式,就不进行校验
    string str;
    cin >> str;
    cout << calculate(str);
}
  1. 判断出栈顺序是否合法

问题:给你个n表示1-n的入栈顺序,再输入一个出栈顺序,判断是否合法

如n=4,表示1234入栈顺序,则4321是合法出栈顺序,1423不是

思路:使用一个栈,先将入栈序列入栈,判断栈顶是否和出栈当前位置元素相同,相同弹栈,下标++,如果最后入栈序列遍历完栈不为空说明此序列非法


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

bool isValid(int n, vector<int> vect)
{
    stack<int> st;
    for (int i = 0, j = 0; i < n; i++)
    {
        st.push(i + 1);
        while (!st.empty() && st.top() == vect[j])
        {
            st.pop();
            j++;
        } 
    }
    return st.empty();    
}

int main()
{
    int n;
    vector<int> vect;
    cin >> n;
    int temp;
    for (int i = 0; i < n; i++)
    {
        cin >> temp;
        vect.push_back(temp);
    }
    cout << isValid(n, vect);
}
  1. 数组奇偶排序输出

问题:将一个数组中偶数大到小排序,奇数小到大排序,交叉输出,先输出奇数


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

int main()
{
    int n;
    cin >> n;
    vector<int> vect;
    vector<int> v1;//奇数 
    vector<int> v2;//偶数
    for (int i = 0;i < n; i++)
    {
        int x;
        cin >> x;
        if (x % 2 == 0)
            v2.push_back(x);
        else
            v1.push_back(x);    
    }
    int size1 = v1.size();
    int size2 = v2.size();

    sort(v1.begin(), v1.end());//升序 
    sort(v2.rbegin(), v2.rend());//降序 
    for (int i = 0, j = 0; i < size1 || j < size2; i++, j++)
    {
        if (i < size1)
        {
            cout << v1[i] << " ";
        }
        if (j < size2)
        {
            cout << v2[j] << " ";
        }
    }
     return 0;
}
  1. 英文语句倒置

问题:区别前面一个,这是单词从后向前输出

输入:student. a am i

输出:i am a student.


#include<iostream>
#include<stack>
using namespace std;
int main()
{
    string str;
    getline(cin, str);
    stack<string> st;
    int end;
    int size = str.size();
    int i = size - 1;
    
    string ans = "";
    
    while (i > -1)
    {
        end = i;
        while (i > -1 && str[i] != ' ')
        {
            i--;
        }
        
        ans += str.substr(i + 1, end - i);
        
        while (i > -1 && str[i] == ' ')
        {
            i--;
            ans += " ";
        }
    }

    cout << ans;
    return 0;
}
  1. 水仙花数

问题:水仙花数是指n(n>=3)位数,每个位上数字n次幂之和等于本身,输入n输出满足条件的所有水仙花数


#include<iostream>
#include<cmath> 
using namespace std;
int main()
{
    int n;
    cin >> n;
    if (n < 3)
        return 0;
        
    for (int i = pow(10, n - 1); i < pow(10, n); i++)
    {
        int temp = i;
        int sum = 0;
        while (temp > 0)
        {
            sum += pow(temp % 10, n);
            temp /= 10;
        }
        if (sum == i)
            cout << i << endl;
    }
    return 0;
}
  1. 完全数

定义:一个完全数的所有真因子(除了自身以外的约数)的和等于本身,如6的真因子1,2,3的和等于6,那么他就是完全数

问题:求出1000以内完全数


#include<iostream>
#include<cmath>
using namespace std;
int main()
{
    int n;
    cin >> n;
    for (int i = 1; i < n; i++)
    {
        int sum = 0;
        for (int j = 1; j < i; j++)
        {
            if (i % j == 0)
            {
                sum += j;
            }
        }
        if (sum == i)
        {
            cout<<i<<" ";
        }
    }
    return 0;
}
  1. 身份验证

问题:判断一个身份证的合法性


#include<iostream>
using namespace std;
bool IsLeapYear(int year)
{
    if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0))
        return true;
    return false;
}

bool IsNumber(char s)
{
    if ('0' <= s && s <= '9')
        return true;
    return false;
}

int CheckId(string id)
{
    if (id.size() != 18)
        return 1;
            
    if (!IsNumber(id[17]) && id[17] != 'X')
        return 3;
                
    for (int i = 0; i < 17; i++)
        if (!IsNumber(id[i]))
            return 2;
            
    int year = stoi(id.substr(6, 4));//字符串转十进制整数 
    
    if (year > 2017 || year < 1900)
        return 4;    
        
    int month = stoi(id.substr(10, 2));
    
    if (month > 12 || month < 1)
        return 5;
        
    int day = stoi(id.substr(12, 2));
    
    int months[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    
    if (IsLeapYear(year))
        months[1] = 29;
        
    if (months[month - 1] < day || day < 1)
        return 6;    
        
    return 0;
}
int main()
{
    string id;
    cin >> id;
    cout << CheckId(id);
    return 0;
 } 
  1. 字符串字符加一

问题:输入一字符串(a-z)将其每个字符加一,a-b,b-c.....z-a,如果出现连续的几个一样的字符,如aaa,第一个a变b,第二个a变c,第三个又变b,例如abbbz->bcdca


#include<iostream>
using namespace std;

//在原来基础上加1或者加2 
char trans(char c, int add)
{
    if (add == 1)
    {
        if (c == 'z')
            return 'a';
        else
            return char(c + 1);
    }
    else if (add == 2)
    {
        if (c == 'y')
            return 'a';
        else if (c == 'z')
            return 'b';
        else
            return char(c + 2);
    }
}

int main()
{
    string s1;
    cin >> s1;
    string s2 = "";
    
    char rc;//存储上一个字符用来比较 
    bool isAddTwo = true;//是否在原来基础上加2,第一次遇见和上一个重复需要加2 
    
    for (int i = 0; i < s1.size(); i++)
    {
        if (i == 0)
        {
            rc = s1[i];
            s2.push_back(trans(rc, 1));
            continue;
        }
        
        if (s1[i] == rc)
        {
            if (isAddTwo)
            {
                s2.push_back(trans(rc, 2));
                isAddTwo = false;//加过一个2,下个重复要加1,赋值false 
            }
            else
            {
                s2.push_back(trans(rc, 1));
                isAddTwo = true;//加了一次1,下次重复加2 
            }
        }
        else
        {
            rc = s1[i];
            s2.push_back(trans(rc, 1));
            isAddTwo = true;//当前字符和上一个不等,条件赋值初始值true; 
        }
    }
     cout <<  s2;
}
  1. 字符串分割过滤输出

问题:输入一串字符串用","分开,过滤掉重复的,转为数组再顺序输出,输出时连续的数字只输入最开始和结尾的

输入:1,90,2,4,110,3,110

输出:1 4 90 110 (1234只输出1和4)


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

void print(set<int> set)
{
    int size = set.size();
    vector<int> vect(set.begin(), set.end());
    
    for (int i = 0; i < size; i++)
    {
        if (i == 0 || i == size - 1 || vect[i-1] + 1 != vect[i] || vect[i + 1] - 1 != vect[i])
            cout << vect[i] << " ";
    }
}

void function(string str)
{
    set<int> set;
    int size = str.size();
    int i = 0;
    while (i < size)
    {
        int start = i;
        while (i < size && str[i] != ',')
        {
            i++;
        }
        set.insert(stoi(str.substr(start, i - start)));
        i++;
    }
    print(set);
}


int main()
{
    string str;
    cin >> str;
    function(str);
}
  1. 括号匹配

题目:在某个字符串(长度不超过100)中有左括号、右括号和大小写字母;规定(与常见的算数式子一样)任何一个左括号都从内到外与在它右边且距离最近的右括号匹配。写一个程序,找到无法匹配的左括号和右括号,输出原来字符串,并在下一行标出不能匹配的括号。不能匹配的左括号用"$“标注,不能匹配的右括号用”?"标注

输出格式:对每组输出数据,输出两行,第一行包含原始输入字符,第二行由 “$” , “?” 和空格组成, “$” 和 “?” 表示与之对应的左括号和右括号不能匹配。

样例输入

((ABCD(x)

)(rttyy())sss)(

样例输出

((ABCD(x)

$$

)(rttyy())sss)(

? ?$


#include<iostream>
#include<stack>
using namespace std;
string getStr(int length)
{
    string str = "";
    for (int i = 0; i < length; i++)
    {
        str += " ";
    }
    return str;
}

int main()
{
    string input;
    
    while (cin >> input)
    {
        int length = input.size();
        string str = getStr(length);//初始和原串一样长的空格字符串
        
        stack<pair<char, int>> st;//一个括号和它的下标
        
        for (int i = 0; i < length; i++)
        {
            if (input[i] == '(')//左括号入栈
            {
                st.push(pair<char, int> ('(', i));
            }
            else if (input[i] == ')')//右括号出栈
            {
                if (!st.empty())
                {
                    st.pop();
                }
                else
                {
                    str[i] = '?';//栈空则右括号匹配不上
                }
            }
        }
        while (!st.empty())//栈不为空说明有不匹配的左括号
        {
            pair<char, int> p = st.top();
            st.pop();
            str[p.second] = '$';
        }
        cout << input << endl << str;
    }
}
  1. 最大子序列和

问题:输入整数N,输入一个序列(N个整数),输出最大子序列和的值,以及该子序列的首元素和尾元素


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

/**
思路:
找到整个数组最大子序列和,可以先找局部最大和,
在局部最大和中再找到最大的一个,在此过程中记录下标 
**/ 
int main()
{
    vector<int> nums = {2,1,-3,4,-1,2,1,-5,4};//输入数组,直接定义一个,懒得输入了 
    //vector<int> nums = {5,4,-1,7,8};
    //vector<int> nums = {-3,-5,-6,-2,-9};
    //vector<int> nums = {7};
    
    int ans = nums[0];//全局子序列最大和 
    int sum = 0;//局部子序列最大和 
    int start = 0;//局部子序列开始下标 
    int end = -1;//局部子序列结束下标 
    pair<int, int> p (0, -1);//最大子序列下标 
    
    for (int i = 0; i < nums.size(); i++)
    {
        if (sum > 0)//sum大于0则对于结果有增益,保留sum并加上当前遍历值 
        {
            sum += nums[i];
            end = i;
        }
        else//sum小于0,说明前面部分序列和没有必要往后加,此时sum取值遍历值 
        {
            sum = nums[i];
            start = i;
        }
        
        if (sum > ans)//比较大小,并记录最大下标 
        {
            p.first = start;
            p.second = end;
            ans = sum;
        }
    }
    cout << ans << endl << p.first << " " << p.second;
}

最大和为6,从下标3到6的区间,是4 -1 2 1

  1. 哈弗曼树带权路径长度

问题:给出一个序列,构建huffman树,利用程序计算出带权路径长度

思路:一般是利用叶子节点值乘以层数再求和,也可以直接求和非叶子节点


#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
 
int huffman(vector<int> vec)
{
    int size = vec.size();
    if (size == 1)
    {
        return 0;//没有非叶子节点,返回0 
    } 
    int sum = 0;
    while(size > 1)
    {
        sort(vec.rbegin(), vec.rend());   //先对数组排序(降序)
        
        int a = vec.back();
        vec.pop_back();
        
        int b = vec.back();
        vec.pop_back();
        
        vec.push_back(a + b); //消除原来两元素,增加新元素
        
        sum += a + b; //累计非叶子结点权值和
        size--;
    }
   return sum;
}
int main() 
{
    vector<int> vec = {3,2,6,15,9,17,14,16};
    cout << huffman(vec);//最后输出229 
}

复试面试

面试在第二天早上开始,政审是一起进行,面试靠后的先政审。政审就问问学习/工作经历,十分轻松。面试是在飞云楼的教室等着,叫到名字就去面试教室外面等着。面试一开始就是标准的20分钟,但是我排到下午五点多,到我自己就十一二分钟。进去里面坐了六七个老师,先是中文自我介绍,然后是抽英语口语题,一个条子上二选一,先是读出来,我就思考了十几秒,就让我开始回答,本来我口语不行,结果还没想好说什么就开始作答,说的是没有逻辑,自我感觉就是胡说八道。然后问了毕设,因为我有工作经验,就写在了简历上,没有写本科时期的项目,但是工作内容没问到太多,就问我为什么辞职考研,以及你觉得考上研就能改变现状吗(类似的意思,原话有些记不清了)。我还想着问专业知识,之前准备了很多,结果没问,就说没问题了吧,那就下一位。我出去一看才十一二分钟,感觉凉凉。不过还是上岸了。

复试出成绩

复试成绩是在面试第二天早上出,会贴在飞云楼二楼门口,同时学院官网也会公布,之后当天选择导师签订一个表上交,就可以走了。

成绩计算细则如下:

总成绩=初试总分/5*0.5+复试笔试成绩*0.1+复试面试成绩*0.4

复试笔试成绩(计算机类专业)=专业笔试成绩*0.5+上机成绩*0.5

复试面试成绩=专业综合能力测试成绩*0.8+英语听力成绩*0.1+口语成绩*0.1

总结

兰大复试初试各占一半,因此复试一定要重视,特别是英语基础不好的的,听力口语早早练起来。切莫以为分值小就不重视。可能关键时候就是0.几分就是成功与失败的不同命运。还有上机测试,虽然今年很简单,但是仍然有一大批人因为上机不合格直接被刷,可以说,考研之路每一步都是要脚踏实地的走。既然走到了复试,更要拿出像初试复习时的努力,否则就会功亏一篑。之后计算机大概率是越来越卷,所以未来的学弟学妹,继续加油!理想主义的花最终会盛开在浪漫主义的土壤里,我们终将上岸!

最后,码字不易,点个赞吧!如果需要帮助的同学可以留言,我看到会回复的。

  • 12
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值