计算机机试题(未完善)

1、2019南大计算机本科开放日机试题(最小新整数)

给定一个十进制正整数n(0 < n < 1000000000),每个数位上数字均不为0。n的位数为m。
现在从m位中删除k位(0<k < m),求生成的新整数最小为多少?
例如: n = 9128456, k = 2, 则生成的新整数最小为12456

输入
第一行t, 表示有t组数据;
接下来t行,每一行表示一组测试数据,每组测试数据包含两个数字n, k。
输出
t行,每行一个数字,表示从n中删除k位后得到的最小整数。

样例输入
2
9128456 2
1444 3
样例输出
12456
1

相对位置可以变的情况下:

#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
#include <vector>
using namespace std;
int main(void){
    string str;
    int k, t;
    cin >> t;
    vector<int> vec[t];
    for(int i = 0; i < t; i++){
        cin >> str >> k;
        for(int j = 0; j < str.size(); j++){
            vec[i].push_back(str[j]-48);
        }
        sort(vec[i].begin(), vec[i].end());
        vec[i].erase(vec[i].end()-k, vec[i].end());
    }
    for(int i = 0; i < t; i++){    
        copy(vec[i].begin(), vec[i].end(), ostream_iterator<int>(cout, ""));
        cout << endl;
    }
    
    return 0;
}

相对位置不可以改变:

/**
 * 思路:最长上升子序列的变种
 *      每遍历到字符串中的字符,若存在比当前字符大的字符,则删除之
 *      直到删除的个数已为k 或遍历到了 最后一个字符为止
 * 
*/
#include <iostream>
#include <string>
#include <cstring>
using namespace std;

int main() {

    string num;
    int k;
    cin >> num >> k;
    if(k == 0) {
        cout << num;
        return 0;
    }

    int len = num.length();
    int finalLen = len - k;
    if(finalLen <= 0) {
        cout << "";
        return 0;
    }
    int flag[len];
    memset(flag,0,sizeof(flag));

    int i = 1;
    int j = 0;
    // 有可能存在 12345 这种删除字符数目不够k 的情况
    // 则将前 len - k 个 字符打印之
    while(i < len && k > 0) {
        int a = num[i] - '0';
        for(int j = 0;j < i;j++) {
            int b = num[j] - '0';
            if(a < b && flag[j] == 0) {
                flag[j] = 1;
                k--;
                if(k == 0) {
                    break;
                }
            }
        }
        i++;
    }

    for(int i = 0;i < len;i++) {
        if(flag[i] == 0 && finalLen > 0) {
            cout << num[i];
            finalLen--;
        }
    }

    return 0;
}

2、暨南大学-计算机机试(合并果子问题)

其实,就是一道经典的哈夫曼问题,大致解法:

#include <cstdio>
#include <queue>
using namespace std;

//代表小顶堆的优先队列
priority_queue<long long, vector<long long>, greater<long long> > q;

int main(void){
    int n; //n堆果子
    long long temp, x, y, ans = 0;
    scanf("%d", &n);
    for(int i = 0; i < ans; i++){
        scanf("%lld", &temp);  //将初始重量压入优先队列
        q.push(temp);
    }

    while(q.size() > 1){  //只要优先队列中至少有两个元素
        x = q.top();
        q.pop();
        y = q.top();
        q.pop();
        q.push(x+y);  //取出堆顶的两个元素,求和后压入优先队列
        ans += x+y;   //累计求和的结果
    }
    
    printf("%lld\n", ans); //ans即为消耗的最小体力
    return 0;
}

hyy做法:容器中当前元素的下一个元素的值加上当前元素,最后减去容器中第一个元素即为最小带权路径

#include<iostream>
#include<vector>
#include<functional>
#include <numeric>
#include<algorithm>
using namespace std;
int main(){
	int n,x,a[1000],b[1000],sum=0;
	cin>>n;
	int m = n;
	while(m--){
		cin>>x;
		a[m]=x;
	}
	vector<int> v(a,a+n);
	sort(v.begin(),v.end());
	vector<int>::iterator i=v.begin();
	//vector<int>::iterator i1=v.begin();
	//cout << "=====" << endl;
	for(;i!=v.end()-1;i++)
	    *(i+1)+=*(i);
	
	sum = accumulate(v.begin(), v.end(), 0);
	//cout << "sum : " << sum << endl;
	cout<<sum-*v.begin() << endl;
	return 0;
}

3、求解100以内的素数

解法一:正常存储素数表

#include <cstdio>
#include <cmath>
bool isPrime(int n){ //判断n是否是素数
    if(n <= 1)
        return false;
    int sqr = (int)sqrt(1.0*n);
    for(int i = 2; i <= sqr; i++){
        if(n % i == 0)
            return false; 
    }
    return true;
}

int prime[101], num = 0; //素数的个数
void findPrime(){ //求素数表
    for(int i = 1; i < 101; i++){
        if(isPrime(i) == true){
            prime[num++] = i;
            p[i] = true;
        }
    }
}

int main(void){
    findPrime();
    for(int i = 0; i < num; i++){
        printf("%d", prime[i]);
        if(i < num-1){
            printf(" ");
        }
    }

    return 0;
}

解法二:埃式筛法

#include <cstdio>
const int maxn = 101;
int prime[maxn], num = 0; //素数的个数
bool p[maxn] = {0};  //记录当前下标代表的值是否是素数
void findPrime(){
    for(int i = 2; i < maxn; i++){
        if(p[i] == false){
            prime[num++] = i;
            
            //筛去i~100之间所有i的倍数
            for(int j = i + i; j < maxn; j += i){
                p[j] = true;
            }
        }
    }
}

int main(void){
    findPrime();
    for(int i = 0; i < num; i++){
        printf("%d", prime[i]);
        if(i < num-1){
            printf(" ");
        }
    }
    
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_42067873/article/details/106819691