2005年浙江大学计算机学院考研上机复试 上机试题及参考答案

1.第一题 A+B

在这里插入图片描述

C语言代码

#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<malloc.h>

int main(){
    const char data[12][6] = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "+", "="};
    unsigned a, b; //转换后的参数表达式参数, 如a+b(123+456)
    unsigned i, j, k; //临时变量, 作为下标
    char str[100]; //输入字符串, 足够大容量
    char temp[6]; //临时字符串, 用于检索数字, 如"one" -> 1
    char result[301]; //转换后的表达式参数, 如"123+456="

    do{
        a = b = i = j = k = 0; //初始化变量
        memset(str, 0, sizeof(str));
        memset(temp, 0, sizeof(temp));
        memset(result, 0, sizeof(result));

        gets(str); //获取输入字符串, 不能使用scanf, 因为有空格
        for(i = 0, k = 0; i < strlen(str); ++i){
            for(j = 0; !isspace(str[i]) && i < strlen(str); ++i, ++j){ //提取一个单词
                temp[j] = str[i];
            }
            temp[j] = '\0'; //字符串结束标记

            for(j = 0; j < 12; ++j){ //把这个单词转换为数字
                if(strcmp(temp, data[j]) == 0){ 
                    if( j <= 9) result[k++] = j + '0'; //转换后0-9
                    if( j == 10) result[k++] = '+';
                    if( j == 11) result[k++] = '=';
                    break; //找到匹配数字就不必再搜索了
                }
            }
        }
        result[k] = '\0'; //字符串结束标志, result形式"123+456="
        sscanf(result, "%d+%d=", &a, &b); //用sscanf来获得a,b的值
        if(a==0 && b==0) break; //A,B同时为0则退出程序
        else printf("%d\n", a + b); //打印输出A + B的数值
    }while(1);

    return 0;
}

2.谁是开门关门的人?

在这里插入图片描述
在这里插入图片描述

C语言代码

#include<stdio.h>
#include<malloc.h>
#include<string.h>

typedef struct{
    char id[16]; //证件号码长度不超过15位
    char cometime[9]; //时间格式00:00:00
    char leavetime[9]; //时间格式00:00:00
}Record;

int main(){
    int N, M, i; //记录总天数N, 每天记录的条目数M
    Record *pTimeList; //记录该天出入人员的证件号码, 进入时间, 离开时间
    int first, last; //记录每天开门的人和关门的人

    scanf("%d", &N); //读入记录的天数

    while(N--){
        scanf("%d",&M); //读入该天的进出人员数
        pTimeList = (Record*)malloc(M*sizeof(Record));

        for(i = 0, first = 0, last = 0;i < M; ++i){
                scanf("%s%s%s", pTimeList[i].id, pTimeList[i].cometime, pTimeList[i].leavetime);
                if(i==0){ //将第一个设为对比值
                    continue;
                }else{ //不需要对comeTime或者lastTime进行删减,直接对比
                    if(strcmp(pTimeList[first].comeTime, pTimeList[i].cometime) > 0){
                        first = i; //更换first
                    }
                    if(strcmp(pTimeList[i].leavetime, pTimeList[i].leavetime) < 0){
                        last = i;//更换last
                    } 
                }
        }

        printf("%s %s\n",pTimeList[first].id, pTimeList[last].id);
        free(pTimeList);
    }

    return 0;
}

3.分数统计

题目

在这里插入图片描述
在这里插入图片描述

C语言代码

#include<stdio.h>
#include<malloc.h>
#include<string.h>


typedef struct 
{
    char id[21]; //准考证号(<=20字符)
    int score; //该考生总分
}StuInfo;

int main(){
    int N, M, G, n; //考生人数, 题目数, 分数线, 上线考生数量
    int *pMarkList; //第1题至第M题的正整数分值
    StuInfo *pStuinfo; //考生信息

    int i, j, k, a, b, c, m; //临时变量
    StuInfo tmp; //用于排序

    while(scanf("%d",&N)&&N!=0){//读入考生人数N
        scanf("%d%d",&M,&G); //读入题目数和分数线
        pMarkList = (int*)malloc(M*sizeof(int)); //M道题目的分数
        pStuinfo = (StuInfo*)malloc(N*sizeof(StuInfo)); //N个考生
        for(i = 0;i<M;++i){ //读入M题每题分数
            scanf("%d",&(pMarkList[i]));
        }

        for(i = 0, n = 0;i<N;++i){ //读入N个考生信息, i用于计数N次,cnt用于计算上线考生记录
            scanf("%s%d",&(pStuinfo[n].id), &m); //准考证号, 解出题目数量m

            for(pStuinfo[n].score = 0, j = 0;j<m;++j){ //读入答出的m题的题号
                scanf("%d",&a); //读入答对的题号
                pStuinfo[n].score += pMarkList[a-1]; //因为题目号从1开始, 计算该考生的总分
            }
            if(pStuinfo[n].score >=G){ //如果考生上线则记录下来
                n++; //否则不记录, 便于排序
            }
        }

        for(i = 0;i < n - 1;++i){//输入完毕, 对上线考生按分数线排序, 降序
            for(k = i, j = i + 1;j<n;++j){ //如果有比pStuinfo[i]大的,把它和pStuinfo[i]交换
                if(pStuinfo[n].score > pStuinfo[k].score){
                    k = j;
                }
            }

            tmp = pStuinfo[k];
            pStuinfo[k] = pStuinfo[i];
            pStuinfo[i] = tmp;
        }

        for ( i = 0; i < n; i+=k)
            { //相同分考生再按照准考证号排序
                //统计相同分数考生人数
                for(k  = 1, j = i + 1;j <n ;++j){
                    if(pStuinfo[i].score == pStuinfo[j].score){
                        k++;
                    }
                    else
                    {
                        break;
                    }
                }

                //下标i到i+k的考生分数相同, 对这k个考生排序, 升序
                for(a = i; a<=i+k-1;a++){
                    for(c = a, b = a + 1;b<=i+k;++b){
                        if(strcmp(pStuinfo[c].id, pStuinfo[b].id)){
                            c = b;
                        }
                    }

                    tmp = pStuinfo[a];
                    pStuinfo[a] = pStuinfo[c];
                    pStuinfo[c] = tmp;
                }
            }

            printf("%d\n", n);//排序完毕, 按照要求输出, 上线人数

            for(i = 0;i<n;++i){//和每个上线考生的准考证号和总分数
                printf("%s %d\n",pStuinfo[i].id, pStuinfo[i].score);
            }

            free(pMarkList);
            free(pStuinfo);
    }

    return 0;
}

4.最大连续子序列

在这里插入图片描述
在这里插入图片描述

C语言代码

#include<stdio.h>
#include<malloc.h>
#include<limits.h>

int main(){
    long int K, last; //输入数据个数K<1000; 最大子序列最后一个元素的下标last
    long int ThisSum, MaxSum, TmpMaxSum, index, *pList;

    while(scanf("%d",&K) && K){
        ThisSum = 0;
        MaxSum = TmpMaxSum = last = LONG_MIN;
        pList = (long int*)malloc(K*sizeof(long int));

        for(index = 0;index < K;index++){
            scanf("%d", &(pList[index]));
            ThisSum += pList[index];

            if(ThisSum > MaxSum){ //输入含有正数时, 忽略最大子序列中首尾0的影响
                MaxSum = ThisSum; //更新MaxSum
                if(MaxSum > TmpMaxSum){
                    //保证最大子序列起始位置在输入串的最前面
                    TmpMaxSum = MaxSum;
                    last = index;
                }
            }

            if(ThisSum <0 ) ThisSum = 0;
        }

        //trace back to find first number of the max subsequence
        for(TmpMaxSum = 0, index = last;index>=0;index--){
            TmpMaxSum += pList[index];
            if(TmpMaxSum == MaxSum){
                break;
            }
        }

        if(MaxSum<0) { //K个数字都是负数, 定义最大和为0, 输出首尾元素
            printf("%ld %ld %ld\n",0, pList[0], pList[k-1]);
        }else{
            printf("%ld %ld %ld\n",MaxSum,pList[index],pList[last]);
        }

        free(pList);
    }

    return 0;
}

C语言代码

#include<stdio.h>
#include<malloc.h>
#include<limits.h>

int main(){
    long int K, last; //输入数据个数K<1000; 最大子序列最后一个元素的下标last
    long int ThisSum, MaxSum, TmpMaxSum, index, *pList;

    while(scanf("%d",&K) && K){
        ThisSum = 0;
        MaxSum = TmpMaxSum = last = LONG_MIN;
        pList = (long int*)malloc(K*sizeof(long int));

        for(index = 0;index < K;index++){
            scanf("%d", &(pList[index]));
            ThisSum += pList[index];

            if(ThisSum > MaxSum){ //输入含有正数时, 忽略最大子序列中首尾0的影响
                MaxSum = ThisSum; //更新MaxSum
                if(MaxSum > TmpMaxSum){
                    //保证最大子序列起始位置在输入串的最前面
                    TmpMaxSum = MaxSum;
                    last = index; //现在找到的最大值和的末尾元素
                }
            }

            if(ThisSum < 0) ThisSum = 0;
        }

        //trace back to find first number of the max subsequence
        for(TmpMaxSum = 0, index = last;index>=0;index--){
            TmpMaxSum += pList[index];
            if(TmpMaxSum == MaxSum){ //这时也找到了index
                break;
            }
        }

        if(MaxSum<0) { //K个数字都是负数, 定义最大和为0, 输出首尾元素
            printf("%ld %ld %ld\n",0, pList[0], pList[k-1]);
        }else{
            printf("%ld %ld %ld\n",MaxSum,pList[index],pList[last]);
        }

        free(pList);
    }

    return 0;
}

5.畅通工程

在这里插入图片描述
在这里插入图片描述

4城2路
4 2
1 3
4 3

3城3路
3 3
1 2
1 3
2 3

5城2路
5 2
1 2
3 5

999城0路
999 0

算法:

并查集:如果两个城镇非连通,则将它们各自所在树的根结点连通即可;每次合并城镇时将城镇数-1,最后只需要输出城镇
数-1即可(N个城镇用N-1条路即可连接).

C语言代码

//并查集 
#include<stdio.h>
#include<stdlib.h>

int count=0;
int *arr;
int flag[1005];

int findFather(int jieDian){
    return jieDian==arr[jieDian]?jieDian:findFather(arr[ arr[jieDian] ]);
}

int main(){

    while(1){

        int N;
        scanf("%d",&N);
        if(N==0){
            break;
        }
        int sava_N=N;
        count++;
        int M;
        scanf("%d",&M); 
        arr=(int *)malloc(sizeof(int)*(N+1)); //存储城镇 
        for(int i=1;i<=N;i++){
            arr[i]=i;    //指向本身
        }
        
        for(int i=1;i<=M;i++){
            int relation_One;
            int relation_Two;
            
            scanf("%d%d",&relation_One,&relation_Two);
            int fa_One=findFather(relation_One);
            int fa_Two=findFather(relation_Two);
            
            if(fa_One!=fa_Two) {
                sava_N--;
                if(fa_One<fa_Two){
                    arr[fa_Two]=fa_One;
                }
                else{
                    arr[fa_One]=fa_Two;
                }
            }
        }
        
        flag[count]=sava_N-1;
    }
    
    for(int i=1;i<=count;i++){
        printf("%d\n",flag[i]);
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值