2018年复旦大学机试题

一、计算机学院

1、
给出一个序列,求序列的众数。众数就是一个序列中出现次数最多的数字。 如果不唯一,则输出较小的那个值。 第一行输入一个数代表序列有几个数字。 1<=n<=10^5 每个数字在 int 范围内

样例:
输入:(第一个代表有几个数字)
8
10 3 8 8 3 2 2 2

输出 :
2

送分题,设一个hash表记录每个数字出现的次数,最后从小到大遍历hash表(注意不能从大到小遍历),记录出现次数最多的数。

#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 100000000;
int hashtable[maxn] = {0};
int main(){
    int n, x;

    scanf("%d", &n);
    for(int i = 0; i < n; i++){
        scanf("%d", &x);
        hashtable[x]++;
    }
    int k = 0, ans = hashtable[0];
    for(int i = 0; i < maxn; i++){
        if(hashtable[i] > ans){
            ans = hashtable[i];
            k = i;
        }
    }
    printf("%d", k);
    return 0;

}

2、
给定一个字符串,代表一个一元一次方程。 如果有解则求解,输出格式“x=数字”,如果解的个数无穷,输出 “infinite solutions”。如果没有解输出“no solution”
字符串长度不超过 256 。
输入:
10x-2x-8=4x+7+x
输出:
x=5

略难,想了好久,最后想出办法分别遍历等式左边和等式右边。计算两边的x系数和常系数,cox、con、cox1、con1,在将其挪到等式左边计算coxend,conend。最后结果为x = -conend / coxend

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
string str, num;

int strtonum(string s){		//用于将字符串转换成int型数值
    int ans = 0;
    for(int i = 0; i < s.length(); i++){
        ans = ans * 10 + s[i] - '0';
    }
    return ans;
}

int main(){
    getline(cin, str);
    int denghaopos = str.find("=");
    int cox = 0, con = 0;   //x系数,常系数
    int flag = 1;       //初试默认系数为正
    for(int i = 0; i <= denghaopos; i++){        //等号左边
        if(str[i] >= '0' && str[i] <= '9'){
            num += str[i];
        }else if(str[i] == 'x'){
            if(str[i - 1] == '+' || str[i - 1] == '-' || i - 1 == -1) num += '1';
            cox += strtonum(num) * flag;
            num.clear();
        }else if(str[i] == '+'){
            if(num.empty()){
                flag = 1;
            }else{
                con += strtonum(num) * flag;
                num.clear();
                flag = 1;
            }
        }else if(str[i] == '-'){
            if(num.empty()){
                flag = -1;
            }else{
                con += strtonum(num) * flag;
                num.clear();
                flag = -1;
            }
        }else if(str[i] == '='){
            if(num.empty()){
                flag = 1;
            }else{
                con += strtonum(num) * flag;
                num.clear();
                flag = 1;
            }
        }
    }
    int cox1 = 0, con1 = 0;     //等号左边的X系数、常系数
    for(int i = denghaopos + 1; i < str.length(); i++){ //等号右边
        if(str[i] >= '0' && str[i] <= '9'){
            num += str[i];
        }else if(str[i] == 'x'){
            if(str[i - 1] == '+' || str[i - 1] == '-' || str[i - 1] == '=') num += '1';
            cox1 += strtonum(num) * flag;
            num.clear();
        }else if(str[i] == '+'){
            if(num.empty()){
                flag = 1;
            }else{
                con1 += strtonum(num) * flag;
                num.clear();
                flag = 1;
            }
        }else if(str[i] == '-'){
            if(num.empty()){
                flag = -1;
            }else{
                con1 += strtonum(num) * flag;
                num.clear();
                flag = -1;
            }
        }
        if(i == str.length() - 1 && str[i] >= '0' && str[i] <= '9'){
            con1 += strtonum(num) * flag;
            num.clear();
        }
    }
    int coxend = cox - cox1, conend = con - con1;
    if(coxend == 0 && conend == 0){
        printf("infinite solutions");
        return 0;
    }else if(coxend == 0 && conend != 0){
        printf("no solution");
        return 0;
    }
    int ans = (-1) * conend / coxend;
    printf("x=%d", ans);
}

3、
有2n 的地板,用12和 2*1 的骨牌进行铺地板。问共有多少种情况。 结果对 999983 取余 ,1<=n<=10000 。
输入:
6

输出:
13

看着好像题目越短越复杂,其实手动罗列一下n=1、2、3、4的情况就可以知道本题要用递归。(有点像斐波那契)
n = 1时,只有1种情况;
n = 2 时,有2种情况;
n = 3时,地板大小2 * 3,将情况分为22和21两部分,分别对应n=1和n=2的情况。。。列出方程d[i] = d[i - 1] + d[i - 2];i = 3,4,5,6…
边界为d[1] = 1, d[2] = 2;

#include <cstdio>
const int maxn = 100010;

int func(int n){
    if(n == 1){
        return 1;
    }else if(n == 2){
        return 2;
    }else{
        return func(n - 1) + func(n - 2);
    }
}

int main(){
    int n;
    int d[maxn];
    scanf("%d", &n);
    int ans = func(n);
    printf("%d", ans % 999983);
}

二、工研院

1、
输入两个集合,分别求其交集和并集中元素的个数,每个集合中可能存在相同的元素,而最终的交集和并集中应该不存在。
例如:
输入:
4 5
3 4 7 3
4 6 3 2 6
输出:
2 5

算是送分题了吧,设三个集合S1, S2, S3。S1和S2存放题目的输入,S3用于求并集,而交集可以通过设一个hash表或者在最后遍历一遍S1中的元素判断在S2中能否找到。我在这里用的是设hash表的方法。

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

set<int> S1, S2, S3;
bool hashtable[10000010] = {false};
int main(){
    int n, m, x, num = 0;
    scanf("%d%d", &n, &m);
    for(int i = 0; i < n; i++){
        scanf("%d", &x);
        hashtable[x] = true;
        S1.insert(x);
    }
    for(int i = 0; i < m; i++){
        scanf("%d", &x);
        if(hashtable[x] != false) num++;        //用于求交集
        S2.insert(x);
    }
    for(set<int>::iterator i = S1.begin(); i != S1.end(); i++){ //求并集
        S3.insert(*i);
    }
    for(set<int>::iterator i = S2.begin(); i != S2.end(); i++){	//求并集
        S3.insert(*i);
    }
    int num_bing = 0;
    for(set<int>::iterator i = S3.begin(); i != S3.end(); i++){
        num_bing++;
    }
    printf("%d %d", num, num_bing);
    return 0;
}

2、
输入一个数n,输出前n个数的约数的和。(印象中有1s的时间限制,大数据集可能超时,比如100000000)。
例如:
输入:
7
输出:
41

代码简单但分分钟超时(其实可以改变计算约数时的复杂度,不用遍历1~i,从而进行剪枝以降低整体时间复杂度):

#include <cstdio>
#include <cmath>
int main(){
    int n, ans = 0;
    scanf("%d", &n);
    for(int i = 1; i <= n; i++){        //1~n之间的所有数
        for(int j = 1; j <= i; j++){   //计算这些数的约数并相加
            if(i % j == 0){
                ans += j;
            }
        }

    }
    printf("%d", ans);
    return 0;
}

3、
求线段交点,输入两组线段端点(整型),求其交点,不相交和无穷交点输出一句话就行,输出交点带有小数部分。
例如:
输入:
0 0 5 5
0 2 2 0
输出:
1 1

就用y = kx + b来算就好。

#include <cstdio>

int main(){ //y = kx + b
    int a, b, c, d;
    scanf("%d %d %d %d", &a, &b, &c, &d);//第一条线
    double k1 = (d - b) / (c - a);
    double b1 = b - a * k1;
    scanf("%d %d %d %d", &a, &b, &c, &d);//第二条线
    double k2 = (d - b) / (c - a);
    double b2 = b - a * k2;
    if (k1 == k2)
		printf("平行或重合");
	else {
		double x = (b2 - b1) / (k1 - k2), y = k1*x + b1;
		printf("%.2lf %.2lf", x, y);
	}
	return 0;


}


相关推荐
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页