計算機機試題(未完善)

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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章