安大复试上机题
2013/2014 上机
1.菀菀

解决方法:
#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左下+

测试用例:
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.最大值、最小值(排序)

测试用例:
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.矩阵中找最大最小值

测试用例:
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.成绩

解决方法:
#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.找偶数

测试用例:
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.在矩阵中找最值

测试用例:
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.找奇数

测试用例:
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.找完数(质数)

解决方法:
#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.字符串中找单词

测试用例:
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之间以一个空格隔开)
输出格式
输出最少的操作次数

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

浙公网安备 33010602011771号