安大复试上机题

2013/2014 上机

1.菀菀

image

解决方法:

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

int main(){
    int i=1;
    double n=1;
    double sum=1;
    while(n>0.00001){
        n=(1.0)/(2*i+1);
        if(i%2==0)
            sum=sum+n;
        else 
            sum=sum-n;
        i++;
    }
    printf("%lf",sum);
}

2.N x N矩阵,右上0左下+

image

测试用例:
3
3 4 -1
2 1 3
1 2 1

解决方法:

#include<stdio.h>
int main(){
    int n;
    scanf("%d",&n);
    int a[n][n];
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            scanf("%d",&a[i][j]);
        }
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(i>j){
                a[i][j]=a[i][j]+a[j][i];
            }
        }
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(i<j){
                a[i][j]=0;
            }
        }
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            printf("%d ",a[i][j]);
        }
        printf("\n");
    }
}

3.最大值、最小值(排序)

image

测试用例:
10 3
60 11 74 30 43 21 96 55 83 65

解决方法:

#include<stdio.h>
int main(){
    int n,k;
    scanf("%d%d",&n,&k);
    int a[n];
    int i,temp,p,j;
    for(i=0;i<n;i++){
        scanf("%d",&a[i]);
    }
    for (i = 0; i < n - 1; i++) {
		p = i;                            //p用于记录最小元素的下标
		for (j = i + 1; j < n; j++) {       //找到剩下元素中最小的那一个
			if (a[p] > a[j])
				p = j;
		}
		temp = a[i];                        //temp是交换两数时的中间变量
		a[i] = a[p];
		a[p] = temp;
	}
    temp=k;
    i=0;
    printf("三个最小值:");
    while(temp>0){
        printf("%d ",a[i]);
        i++;
        temp--;
    }
    temp=k;
    i=n-1;
    printf("\n三个最大值:");
    while(temp>0){
        printf("%d ",a[i]);
        i--;
        temp--;
    }
}

2015 上机

1.正数相加

由键盘任意输入10个整数。编程序输出其中的正数、所有正数的和,

测试用例:
1 2 3 4 0 0 0 0 -1 0

解决方法:

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

int main(){
    int a;
    int n =0,sumz=0;
    while(n<10){
        scanf("%d",&a);
        n++;
        if(a>0){
            sumz=sumz+a;
        }
    }
    printf("%d",sumz);
}

2.矩阵中找最大最小值

image

测试用例:
2 1 -4 0 3 5 7 -1 10 1 2 15

解决方法:

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

int main(){
    int a;
    int n=0,n1=0,max=-10000,min=10000,mini=0;
    int hang=0;
    while(n<12){
        scanf("%d",&a);
        if(max<a){
            max=a;
        }
        if(min>a){
            min=a;
            mini=n1%4;
        }
        if((n1+1)%4==0){
            printf("第%d行中的最小的值是%d,它的下标是[%d,%d]\n",hang+1,min,hang,mini);
            min=10000;
            hang=hang+1;
            mini=0;
        }
        n++;
        n1++;
    }
    printf("所有元素的最大值是:%d",max);
}

2016 上机

1.成绩

image

解决方法:

#include<stdio.h>
#include<string.h>
char reGrade(int a);
int main(){
    int n=0;
    int a;
    char b;
    while(n<10){
        scanf("%d",&a);
        b=reGrade(a);
        printf("%c",b);
        n++;
    }
}
char reGrade(int a){
    switch (a/10) {
    case 9:
         return 'A' ;
    case 8:
        return 'B';
    case 7:
         return 'C' ;
    case 6:
        return 'D';
    case 5:
    case 4:
    case 3:
    case 2:
    case 1:
        return 'E';
    }
    return 'E';
}

2.找偶数

image

测试用例:
2,3,7,6,8,5,9,11,12,13

解决方法:

#include<stdio.h>

int main(){
    int a;
    char b;
    int n=0;
    int i=0;
    int sum=0;
    while(n<10){
        scanf("%d",&a);
        b=getchar();
        if(a%2==0){
            printf("%d,",a);
            sum=sum+a;
            i++;
        }
        n++;
    }
    printf(" AVE=%d",sum/i);
}

3.在矩阵中找最值

image

测试用例:
4 2 9 3
13 27 88 32
6 45 16 8

解决方法:

#include<stdio.h>
int main(){
    int max=-1000;
    int n=0;
    int a;
    int hang=0,lie=0;
    while(n<12){
        scanf("%d",&a);
        if(a>max){
            max=a;
            lie=n%4+1;
            hang=n/4;
        }
        n++;
    }
    printf("%d,最大值在%d行,第%d列",max,hang+1,lie);
}

2017 上机

1.找奇数

image

测试用例:
11,4,3,2,7,6,8,5,10,9

解决方法:

#include<stdio.h>
int main(){
    int n=0,n1=0;
    int a;
    char b;
    int sum=0;
    while(n<10){
        scanf("%d",&a);
        b=getchar();
        if(a%2==1){
            n1++;
            sum=sum+a;
            if(n!=9)
                printf("%d,",a);
            else
                printf("%d\n",a);
        }
        n++;
    }
    printf("NUM=%d SUM=%d\n",n1,sum);
}

2.找完数(质数)

image
解决方法:

#include<stdio.h>
int main()
{
    int s,m,i;
    for(s=2;s<1000;s++){
        m=0;
        for(i=1;i<s;i++){
            if(s%i==0){
                m=m+i;
            }
        }
        if(m==s){
            printf("%d的因子是",m);
            for(i=1;i<m;i++){
                if(s%i==0)
                    printf("%d,",i);
                }
            
            printf("并且%d=",m);
            for(i=1;i<m;i++){
                if(s%i==0)
                    printf("%d+",i);
            }
            printf(";所以%d是一个完数\n",m);
        }
    }
    return 0;
}

3.字符串中找单词

image

测试用例:
this is a book
输出示例:
this  4 
is   2 
a     1 
book     4 
the longest word is:this,book

解决方法:
法1:整串输入,整串处理

#include<stdio.h>
#include <string.h>
int main(){
    char str[40];
    char s[15][15];
    int lens[10];
    fgets(str,40,stdin);
    int len=strlen(str);
    //最后一个字符是换行符
    int i,j1=0,j2=0;
    str[len-1]=' ';//没有空格我自己加个空格,我就保证后面有空格就行
    for(i=0;i<len;i++){
        if(str[i]!=' '){
            s[j1][j2]=str[i];
            j2++;
        }else if(str[i]==' '){
            lens[j1]=j2;
            j1++;
            j2=0;
        }
    }
    int max=lens[0];
    for(i=0;i<j1;i++){
        printf("%-5s %d \n",s[i],lens[i]);
        if(max<lens[i])
            max=lens[i];
    }
    printf("the longest word is:");
    for(i=0;i<j1;i++){
      if(i==(j1-1)){
        printf("%s",s[i]);
      }else{
        if(lens[i]==max){
          printf("%s,",s[i]);
        }
      }
   }
    return 0;
}

法1:单个字符,单个处理

#include<stdio.h>
#include <string.h>
int main(){
  //一个个字符判断
  char a;
  char s[20][20]={0};//存储单词
  int num=0;
  int i1=0,i2=0;
  int lens[20];
  int max=0;
  while(scanf("%c",&a)){
    if(a!=' '){     
      //因为最后一个字符是换行赴,它会自动存进去,所以就不要存了
      if(a=='\0'||a==EOF||a=='\n'){
        lens[i1]=i2;
        printf("%s %d \n",s[i1],lens[i1]);
        i1++;
        i2=0;
        break;
      }
      s[i1][i2]=a;
      i2++;
    }else if(a==' '){//遇到空格就输出
      lens[i1]=i2;
      printf("%s %d \n",s[i1],lens[i1]);
      i1++;
      i2=0;
    }
  }
  int i=0;
  for(i=0;i<i1;i++){
        if(max<lens[i])
            max=lens[i];
    }
    printf("the longest word is:");
    for(i=0;i<i1;i++){
      if(i==(i1-1)){
        printf("%s",s[i]);
      }else{
        if(lens[i]==max){
          printf("%s,",s[i]);
        }
      }
   }
  return 0;
}

2018 上机

1.递归

给定一个函敷;
F(0)=O;
F(1)=1;
Fn=F(n-1)+F(n-2),n>1
程序输入一个整数,0<n<100000,输入 F(n)的值,结果对854562545取余。

你不要我用递归,我偏用

#include <stdio.h>
int Fac(int n);
int main(){
	int n;
	scanf("%d",&n);
	printf("%d",Fac(n)%854562545);
	return 0;
}
int Fac(int n){
   if(n==0||n==1){
     return n;
   }else
     return Fac(n-1)+Fac(n-2);
 }

2.用数组模拟栈

问题描述:定义一个单调栈;每次整数n入栈时,如果栈顶元素大于 n,则栈顶元素出栈,并且继续判断栈顶元素是否大于n,大于则出栈,重复操作,直到栈顶元素不大于 n,n 入栈。入栈完毕。例如栈中元素为237,如栈元素为6,则7出栈,6入栈,最后结果为2 3 6:(思路提示。类似于插入打序,边输入边入栈,用数组维护栈。)
输入:
第一行输入一个整数0<n<100000,表示待入栈的元素序列
第二行输入n个待入栈的数
输出:
输出所有元素入栈后,栈的元素

Input
3
512
Output
12

解决方法:

#include <stdio.h>
#include <stdlib.h>
int main(){
    int n,i;
    int temp;
    int s[100];//用数组代替栈
    int top = -1;//栈的标值
    scanf("%d",&n);
    for(i=0;i<n;i++){
        scanf("%d",&temp);
        if(top == -1){//栈为空时
            top++;
            s[top] = temp;
        }else{
            while(top != -1 && s[top] > temp){//大于则出栈,否则入栈
                top--;
            }
            top++;
            s[top] = temp;
        }
    }
    for(i = 0; i < top; i++){
        printf("%d ",s[i]);
    }
    printf("%d",s[top]);
    return 0;
}

3.队列实现 bfs

题目描述
输入两个整数n(0<n<100001)和k(0<k<100001),通过对n连续进行加1或减1或乘以2这3种操作,使得n最后结果正好等于k(同一种操作可以使用多次也可以不使用),要求最后输出最少的操作次数。
例如:n为5,k为17,通过减1、乘以2、乘以2、加1四次操作得到17,也就是5-1=4,4×2=8、8×2=16,16+1=17.
输入格式
输入两个整数n和k(n和k之间以一个空格隔开)
输出格式
输出最少的操作次数
image

Input
5 17
OutPut
4

解决方法:

#include<stdlib.h>
#include<stdio.h>
struct list{
//用结构体表示每一个节点,用队列来实施bfs
    int n;
    int step;//表示步数
    struct list *next;
};
//n为5,k为17,通过减1、乘以2、乘以2、加1四次操作得到17,也就是5-1=4,4×2=8、8×2=16,16+1=17.
//bfs一层层展开
int main(){//对n连续进行加1或减1或乘以2这3种操作
    int n,m,k;
    struct list *p,*p1,*p2,*p3,*pm;
    scanf("%d %d",&n,&m);
    p=(struct list *)malloc(sizeof(struct list ));
    p->n=n;//当前的值
    p->step=1;//步长
    p->next=NULL;
    pm=p;
    while(p!=NULL){ //每一步-1,+1,*2都保存在链表维护的队列中
        k=p->n;//根节点
        if(k==m) //m为目标
            break;
        //-1
        p1=(struct list *)malloc(sizeof(struct list ));
        p1->n=k-1;
        p1->step=p->step+1;
        p1->next=NULL;
        pm->next=p1;
        //+1
        p2=(struct list *)malloc(sizeof(struct list ));
        p2->n=k+1;
        p2->step=p->step+1;
        p2->next=NULL;
        p1->next=p2;
        //*2
        p3=(struct list *)malloc(sizeof(struct list ));
        p3->n=k*2;
        p3->step=p->step+1;
        p3->next=NULL;
        p2->next=p3;

        pm=p3;
        p1=p;
        p=p->next;
        free(p1);
    }
    printf("%d\n",p->step-1);
    return 0;
}

安大竞赛题

2.区间问题

给定多个区间,计算让这些区间互不重叠所需要移除区间的最少个数。起止相连不算重叠。
输入输出样例
输入是一个数组,数组由多个长度固定为2的数组组成,表示区间的开始和结尾。输出一个整数,表示需要移除的区间数量。

Input: [[1,2],[2,4],[1,3]]
output: 1

在这个样例中,我们可以移除区间[1,3],使得剩余的区间[[1,2],[2,4]互不重叠。

题解
1.在选择要保留区间时,区间的结尾十分重要:选择的区间结尾越小,余留给其它区间的空间就越大,就越能保留更多的区间。
2.因此,我们采取的贪心策略为,优先保留结尾小且不相交的区间。具体实现方法为,先把区间按照结尾的大小讲行增序排序.每次选择结尾最小且和前一个选择的区间不重叠的区间.
3.在样例中,排序后的数组为[[1,2],[1,3],[2,4]]。按照我们的贪心策略,首先初始化为区间[1,2];由于[1,3]与[1,2]相交,我们跳过该区间;由于[2,4]与[1,2]不相交,我们将其保留。因此最终保留的区间为[[1,2],[2,4]]。

解决方法:

#include <stdio.h>
#include <string.h>
int main(){
  char ch;
  int i=0;
  int size=0;
  int nums[100][100];
  scanf("[");
  while(1){
    scanf("[%d,%d]",&nums[i][0],&nums[i][1]);
    size++;
    i++;
    scanf("%c",&ch);
    if(ch==']')
      break;
  }
  //从小到大排序
  int min,temp;
  int j;
  for(i=0;i<size-1;i++){
    min=i;
    for(j=i+1;j<size;j++){
      if(nums[j][1]<nums[min][1])
        min=j;
    }
    //交换
    temp=nums[i][0];
    nums[i][0]=nums[min][0];
    nums[min][0]=temp;
    temp=nums[i][1];
    nums[i][1]=nums[min][1];
    nums[min][1]=temp;
  }
  //后一个比前一个区间开始小,移掉 res++
  int result=0;
  int pre=nums[0][1];
  for(i=1;i<size;i++){
    if(pre>nums[i][0])
      result++;
    else
      pre=nums[i][1];
  }
  printf("%d",result);
}
posted @ 2023-03-10 21:00  太好了还有脑子可以用  阅读(64)  评论(0)    收藏  举报