考研机试练习(KY11KY20)

KY11 二叉树遍历

题目描述

编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。

输入描述:

输入包括1行字符串,长度不超过100。

输出描述:

可能有多组测试数据,对于每组数据,
输出将输入字符串建立二叉树后中序遍历的序列,每个字符后面都有一个空格。
每个输出结果占一行。

输入

abc##de#g##f###

输出

c b e g d f a 

代码

#include <iostream>
#include <string>
using namespace std;
int t;
string pre;
struct TreeNode{
    char val;
    TreeNode* left, *right;
    TreeNode(int x):val(x),left(NULL),right(NULL){}
};
TreeNode* Create_Tree(){
    char c = pre[t++];
    //若是‘#’,说明该节点为空返回上一级节点
    if(c == '#') return NULL;
    TreeNode* root = new TreeNode(c);//若不是#,为本节点赋值
    root->left = Create_Tree();//递归创建左子树
    root->right = Create_Tree();//递归创建右子树
    return root;
}
void inOrder(TreeNode* root){
    if(root == NULL){
        return;
    }
    inOrder(root->left);
    cout << root->val << " ";
    inOrder(root->right);
}
int main(){
    while(cin >> pre){
        t = 0;
        TreeNode* root = NULL;
        root = Create_Tree();
        inOrder(root);
        cout << endl;
    }
    return 0;
}

KY12 玛雅人的秘密

题目描述

玛雅人有一种密码,如果字符串中出现连续的2012四个数字就能解开密码。给一个长度为N的字符串,(2=<N<=13)该字符串中只含有0,1,2三种数字,问这个字符串要移位几次才能解开密码,每次只能移动相邻的两个数字。例如02120经过一次移位,可以得到20120,01220,02210,02102,其中20120符合要求,因此输出为1.如果无论移位多少次都解不开密码,输出-1。

输入描述:

输入包含多组测试数据,每组测试数据由两行组成。
第一行为一个整数N,代表字符串的长度(2<=N<=13)。
第二行为一个仅由0、1、2组成的,长度为N的字符串。

输出描述:

对于每组测试数据,若可以解出密码,输出最少的移位次数;否则输出-1。

输入

5
02120

输出

1

代码

#include <stdio.h>
#include <iostream>
#include <map>
#include <string>
#include <queue>
using namespace std;
map<string, int> M;//M[str]表示str经历的交换次数
queue<string> Q;//队列,用于bfs

string Swap(string str, int i)
{//将字符串i位与i+1位交换
    string newStr=str;
    char tmp=newStr[i];
    newStr[i]=newStr[i+1];
    newStr[i+1]=tmp;
    return newStr;
}

bool Judge(string str)
{//判断字符串中是否含有"2012"
    if(str.find("2012", 0)==string::npos) return false;
    else return true;
}

int BFS(string str)
{//广度优先搜索
    string newStr;
    M.clear();//清空map
    while(!Q.empty()) Q.pop();//清空队列
    Q.push(str);//初始字符串作为起点放入队列
    M[str]=0;//初始字符串经历的交换次数是0
    while(!Q.empty())
    {
        str=Q.front();
        Q.pop();//取出队首,存入str
        for(unsigned i=0; i<str.size()-1; i++)//尝试进行一次交换
        {
            newStr=Swap(str, i);//新字符串由str交换i位和i+1位得到
            if(M.find(newStr)==M.end())//如果这个字符串没出现过
            {
                M[newStr]=M[str]+1;//现在出现过了,且交换次数比他爹多1
                if(Judge(newStr)==true) return M[newStr];//符合要求,收工
                else Q.push(newStr);//不合要求,那继续bfs,把它加入队列
            }
            else continue;//出现过的字符串,不用进行处理
        }
    }
    return -1;//遍历完成,没发现符合要求的字符串,返回-1
}

int main()
{
    int n;
    string str;
    while(scanf("%d", &n)!=EOF)
    {
        cin>>str;//读取字符串(前面读取n好像没啥用)
        if(Judge(str)==true) printf("0\n");//一开始就符合要求的话
        else//初始字符串不符合要求,那就bfs
        {
            int ans=BFS(str);
            printf("%d\n", ans);
        }
    }
    return 0;//大功告成
}

KY13 求最大最小数

题目描述

输入N个(N<=10000)数字,求出这N个数字中的最大值和最小值。每个数字的绝对值不大于1000000。

输入描述:

输入包括多组测试用例,每组测试用例由一个整数N开头,接下去一行给出N个整数。

输出描述:

输出包括两个整数,为给定N个数中的最大值与最小值。

输入

5
1 2 3 4 5
3
3 7 8

输出

5 1
8 3

代码

#include<iostream>
using namespace std;
int main(){
    int number;
    while(cin>>number){
        int* a=new int[number];
        int temp;
        for(int i=0;i<number;i++)
            cin>>a[i];
        int min=1000000,max=-1000000;
        for(int i=0;i<number;i++){
            if(a[i]<min)
                min=a[i];
            if(a[i]>max)
                max=a[i];
        }
        cout<<max<<' '<<min<<endl;
    }
}

KY14 最小邮票数

题目描述

有若干张邮票,要求从中选取最少的邮票张数凑成一个给定的总值。 如,有1分,3分,3分,3分,4分五张邮票,要求凑成10分,则使用3张邮票:3分、3分、4分即可。

输入描述:

有多组数据,对于每组数据,首先是要求凑成的邮票总值M,M<100。然后是一个数N,N<20,表示有N张邮票。接下来是N个正整数,分别表示这N张邮票的面值,且以升序排列。

输出描述:

对于每组数据,能够凑成总值M的最少邮票张数。若无解,输出0。

输入

10
5
1 3 3 3 4

输出

3

代码

#include<stdio.h>
#define INF 1000
int stamp[1000];
int dp[1000];
// 返回最少数量,num表示邮票的个数,deno表示要凑成的面额
int Min_Stamp(int num,int deno){
    int i,j;
    //将状态全部初始化为最多
    for(j=0;j<=deno;++j){
        dp[j]= (j==0)?0:INF;       
    }
    for(i=0;i<num;i++){
        //从后向前寻找若能凑成,且使数量变少就使用,不能也无所谓因为还是INF
        for(j=deno;j>=stamp[i];j--){
            if(dp[j-stamp[i]]!=INF)dp[j]=(dp[j] < dp[j-stamp[i]]+1)? dp[j]: dp[j-stamp[i]]+1;
        }
    }
    return dp[deno]==INF?0:dp[deno];
}
 
int main()
{
    int num,deno;
    while(scanf("%d %d",&deno,&num)!=EOF){
        for(int i=0;i<num;i++)scanf("%d",stamp+i);
        printf("%d",Min_Stamp(num,deno));
    }
    return 0;
}

KY15 abc

题目描述

设a、b、c均是0到9之间的数字,abc、bcc是两个三位数,且有:abc+bcc=532。求满足条件的所有a、b、c的值。

输入描述:

题目没有任何输入。

输出描述:

请输出所有满足题目条件的a、b、c的值。
a、b、c之间用空格隔开。
每个输出占一行。

输入

输出

代码

#include <iostream>

using namespace std;

int main(){
    for(int a = 0; a <= 9; ++a){
        for (int b = 0; b <= 9 ; ++b) {
            for (int c = 0; c <=9 ; ++c) {
                if (a * 100 + b * 110 + c * 12 ==532 ){
                    printf("%d %d %d\n" , a, b, c);
                }
            }

        }
    }
    return 0;
}

KY16 求root(N, k)

题目描述

N<k时,root(N,k) = N,否则,root(N,k) = root(N',k)。N'为N的k进制表示的各位数字之和。输入x,y,k,输出root(x^y,k)的值 (这里^为乘方,不是异或),2=<k<=16,0<x,y<2000000000,有一半的测试点里 x^y 会溢出int的范围(>=2000000000)

输入描述:

每组测试数据包括一行,x(0<x<2000000000), y(0<y<2000000000), k(2<=k<=16)

输出描述:

输入可能有多组数据,对于每一组数据,root(x^y, k)的值

输入

4 4 10

输出

4

代码

#include<iostream>

using namespace std;

int root(int x, int y, int k) {
    if (y == 1) {
        if (x < k)
            return x;
        else {
            while (x >= k) {
                int sum = 0;
                while (x > 0) {
                    sum += x % k;
                    x /= k;
                }
                x = sum;
            }
            return x;
        }
    } else {
        int r = root(x, y / 2, k);
        r *= r;
        if (y % 2 == 1) {
            r *= root(x, 1, k);
        }
        return root(r, 1, k);
    }
}

int main() {
    int x, y, k;
    while (cin >> x >> y >> k)
        cout << root(x, y, k) << endl;
    return 0;
}

KY17 n的阶乘

题目描述

输入一个整数n,输出n的阶乘(每组测试用例可能包含多组数据,请注意处理)

输入描述:

一个整数n(1<=n<=20)

输出描述:

n的阶乘

示例1

输入

3

输出

6

代码

#include<iostream>
#include<vector>
 
using namespace std;
 
int main(){
    vector<long long> dp(21, 1);
    for(int i = 2; i <= 20; i ++){
        dp[i] = dp[i - 1] * i;
    }
    int n;
    while(cin >> n){
        cout << dp[n] << endl;
    }
}

KY18 特殊乘法

题目描述

写个算法,对2个小于1000000000的输入,求结果。 特殊乘法举例:123 * 45 = 1*4 +1*5 +2*4 +2*5 +3*4+3*5

输入描述:

两个小于1000000000的数

输出描述:

输入可能有多组数据,对于每一组数据,输出Input中的两个数按照题目要求的方法进行运算后得到的结果。

输入

123 45

输出

54

代码

#include <iostream>
#include <string>

using namespace std;

int main() {
    string x, y;
    while (cin >> x >> y) {
        int sum = 0;
        for (auto itx : x) {
            for (auto ity : y) {
                sum += (itx - '0') * (ity - '0');
            }
        }
        printf("%d\n", sum);
    }
    return 0;
}

KY19 今年的第几天

题目描述

输入年、月、日,计算该天是本年的第几天。

输入描述:

包括三个整数年(1<=Y<=3000)、月(1<=M<=12)、日(1<=D<=31)。

输出描述:

输入可能有多组测试数据,对于每一组测试数据,
输出一个整数,代表Input中的年、月、日对应本年的第几天。

输入

1990 9 20
2000 5 1

输出

263
122

代码

#include <iostream>

using namespace std;

int daytab[2][13] = {
        {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
        {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
};
bool IsLeapYear(int year){
    return (year % 4 ==0 && year % 100 != 0 ) || (year % 400 == 0);
}
int main(){
    int year, month, day;
    while (scanf("%d %d %d", &year, &month, &day) != EOF){
        int number = 0;
        int row = IsLeapYear(year);
        for (int i = 0; i < month; ++i) {
            number += daytab[row][i];
        }
        number += day;
        printf("%d\n",number);
    }
    return 0;
}

KY20 完数与盈数

题目描述

一个数如果恰好等于它的各因子(该数本身除外)子和,如:6=3+2+1。则称其为“完数”;若因子之和大于该数,则称其为“盈数”。 求出2到60之间所有“完数”和“盈数”。

输入描述:

题目没有任何输入。

输出描述:

输出2到60之间所有“完数”和“盈数”,并以如下形式输出:
E: e1 e2 e3 ......(ei为完数)
G: g1 g2 g3 ......(gi为盈数)
其中两个数之间要有空格,行尾不加空格。

输入

输出

代码

#include<iostream>
#include<cstdio>
#include<vector>

using namespace std;
vector<int> v1, v2;
vector<int>::iterator it;

int main() {
    int sum, temp;
    for (int i = 2; i <= 60; ++i) {//求因子
        sum = 0;
        for (int j = 1; j <= i / 2; ++j) {
            if (i % j == 0) {
                temp = j;
                sum += j;
            }
        }
        if (sum == i) {
            v1.push_back(i);
        }
        if (sum > i)
            v2.push_back(i);
    }
    cout << "E:";
    for (it = v1.begin(); it != v1.end(); it++) {
        cout << " " << *it;//末尾不加空格!!!不然格式会一直错误
    }
    cout << endl;
    cout << "G:";
    for (it = v2.begin(); it != v2.end(); it++) {
        cout << " " << *it;//末尾不加空格!!!不然格式会一直错误
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zhangzizi/p/14352166.html