据江湖传闻,2014年计算机机试分为了上午、下午两批。
先来看上午的题目。
题目地址:A.众数-计算机一2014
直接统计即可。
AC代码:
#include<iostream> #include<cstdio> using namespace std; int a[105]; int main() { int tes; int n,i; while(~scanf("%d",&tes)) { while(tes--) { scanf("%d",&n); for(i=0; i<n; i++) scanf("%d",&a[i]); int cnt=1; //记录出现的次数 int res,ans=0; for(i=1; i<n; i++) { if(a[i]!=a[i-1]) { if(cnt>ans) { ans=cnt; res=a[i-1]; } cnt=1; } else cnt++; } if(cnt>ans) //最后一个数还没判断 { ans=cnt; res=a[i-1]; } printf("%d\n",res); } } return 0; } /* 2 4 1 1 1 2 5 1 1 2 2 3 */
题目地址:B. 旋转图像-计算机一2014
解题思路:
我们可以简化思路,写一个旋转90度的函数。如果选择180度则执行两次,270度,则执行三次。。
PS:记得交换m,n。
AC代码:
#include<iostream> #include<cstdio> using namespace std; char a[55][55]; char b[55][55]; int m,n; void rotate() { int i,j; for(i=0; i<m; i++) //顺时针旋转90度后保存到b数组里 { for(j=0; j<n; j++) b[j][m-1-i]=a[i][j]; } for(i=0; i<n; i++) //保存回a数组 { for(j=0; j<m; j++) a[i][j]=b[i][j]; a[i][j]='\0'; } int tmp=m; //记得交换m,n m=n; n=tmp; } int main() { int tes; int i,j; while(~scanf("%d",&tes)) { while(tes--) { scanf("%d%d",&m,&n); for(i=0; i<m; i++) scanf("%s",a[i]); int d; scanf("%d",&d); d=d/90; //判断要旋转的次数 while(d--) rotate(); for(i=0; i<m; i++) printf("%s\n",a[i]); } } return 0; } /* 2 2 3 111 000 90 3 3 111 101 111 180 */
题目地址:C. 网络的核-计算机一2014
解题思路:
这题的思路就是先用floyd求出任意两点的最短距离,然后看哪个点事要求的点。
PS:记得floyd的顺序是k,i,j,表示初试的时候大题i,j,k顺序写错了。。。
AC代码:
#include<iostream> #include<cstdio> #define maxn 55 using namespace std; int m,n; int dis[maxn][maxn]; void floyd() //floyd的顺序k,i,j { int i,j,k; for(k=1; k<=n; k++) for(i=1; i<=n; i++) for(j=1; j<=n; j++) { if(dis[i][j]>dis[i][k]+dis[k][j]) dis[i][j]=dis[i][k]+dis[k][j]; } } int main() { int tes; int i,j; while(~scanf("%d",&tes)) { while(tes--) { scanf("%d%d",&n,&m); for(i=1; i<=n; i++) //初试化 { for(j=1; j<=n; j++) dis[i][j]=n; dis[i][i]=0; } int a,b; for(i=0; i<m; i++) { scanf("%d%d",&a,&b); dis[a][b]=dis[b][a]=1; } floyd(); int res,mi=100000000; for(i=1; i<=n; i++) //统计每个点到其他所有点的距离和,选最小的 { int tt=0; for(j=1; j<=n; j++) { tt+=dis[i][j]; } if(tt<mi) { mi=tt; res=i; } } printf("%d\n",res); } } return 0; } /* 2 3 3 1 2 1 3 2 3 4 2 1 2 2 3 */
题目地址:D. Python List-计算机一2014
解题思路:
先分析题目大意,总共有四种操作。
a=[]
a.sort()
a.append(int)
a.[int]
用一个map将list的名字和数组下标对应,然后分析每个操作。详见代码。
AC代码:
#include<iostream> #include<cstdio> #include<map> #include<cstring> #define maxn 105 using namespace std; int a[maxn][maxn]; //a[t]表示list映射到t的数组 int len[maxn]; //len[t]表示list映射到t的长度 map <string,int> mq; int main() { int tes,n,i,j; char str[maxn]; char nam[maxn]; while(~scanf("%d",&tes)) { while(tes--) { scanf("%d",&n); mq.clear(); memset(len,0,sizeof(len)); int t=0,x; int l; while(n--) { scanf("%s",str); l=strlen(str); if(str[l-1]==']') { if(str[l-2]=='[') //.[] { for(i=0; i<l; i++) { if(str[i]=='=') break; nam[i]=str[i]; } nam[i]='\0'; //获取list的名字 //printf("%s\n",nam); if(!mq[nam]) { mq[nam]=t; len[t]=0; t++; } else { len[mq[nam]]=0; } } else //.[int] { for(i=0; i<l; i++) { if(str[i]=='[') break; nam[i]=str[i]; } nam[i]='\0'; //获取list的名字 int d=0; //得到int的值 i++; for(i; i<l-1; i++) { d=d*10+(str[i]-'0'); } x=mq[nam]; //cout<<"d:"<<d<<endl; if(len[x]<=d) { printf("ERROR\n"); } else { printf("%d\n",a[x][d]); } } } else { if(str[l-2]=='(') //.sort() { for(i=0; i<l; i++) { if(str[i]=='.') break; nam[i]=str[i]; } nam[i]='\0'; //获取list的名字 x=mq[nam]; int tmp; for(i=0; i<len[x]; i++) { for(j=i+1; j<len[x]; j++) { if(a[x][i]>a[x][j]) { tmp=a[x][i]; a[x][i]=a[x][j]; a[x][j]=tmp; } } } } else { for(i=0; i<l; i++) { if(str[i]=='.') break; nam[i]=str[i]; } nam[i]='\0'; //获取list的名字 x=mq[nam]; int d=0; //得到int的值 i+=8; for(i; i<l-1; i++) { d=d*10+(str[i]-'0'); } a[x][len[x]]=d; len[x]++; } } } } } return 0; } /* 2 5 a=[] a.append(0) a.append(1) a[0] a[1] 8 lista=[] lista.append(123) lista.append(65) lista[0] lista.sort() lista[0] listb=[] listb[0] */
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
再来看看下午的题目。
题目地址:A. 中位数-计算机二2014
解题思路:
n分奇数和偶数讨论,
如果是奇数,直接输出下标为(n/2+1)即可(我是下标从1开始的)
如果是偶数,输出n/2与n/2+1和的一半即可。不过由于输出时要控制不要末尾的0。由于数组里都是int,可以把结果放大10倍,如果可以被10整除,输出int即可。否则输出一位小数(只能是.5)
AC代码:
#include<iostream> #include<cstdio> #include<map> #include<cstring> #define maxn 105 using namespace std; int a[maxn]; int main() { int tes,n,i; while(~scanf("%d",&tes)) { while(tes--) { scanf("%d",&n); for(i=1; i<=n; i++) scanf("%d",&a[i]); if(n%2==1) printf("%d\n",a[n/2+1]); else { int t = ((double(a[n/2])+a[n/2+1])/2)*10; //把结果放大10倍 if(t%10==0) printf("%d\n",t/10); else printf("%.1f\n",double(t)/10); } } } return 0; } /* 2 4 1 1 2 2 5 1 1 2 2 3 */
题目地址:B. 内存分配-网妍14-计算机二14
解题思路:
由于是最佳适应,可以把最开始的内存按照从小到大排序。然后设立一个vis访问数组。每次新来一个就从从开头遍历这个数组,找到第一个>=这个值,并且vis为0(未使用)的,然后把vis置1。详见代码
AC代码:
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #define maxn 105 using namespace std; int a[maxn]; int vis[maxn]; int main() { int tes,n,m,i,j; while(~scanf("%d",&tes)) { while(tes--) { scanf("%d",&n); for(i=0; i<n; i++) scanf("%d",&a[i]); sort(a,a+n); //从小到大排序 memset(vis,0,sizeof(vis)); //vis初始化为0 scanf("%d",&m); int flag,d; for(j=0; j<m; j++) { if(j>0) printf(" "); flag=0; scanf("%d",&d); for(i=0; i<n; i++) { if(a[i]>=d&&!vis[i]) //找到第一个>=d并且未使用的 { vis[i]=1; printf("%d",a[i]); flag=1; break; } } if(!flag) //没找到,输出NULL printf("NULL"); } printf("\n"); } } return 0; } /* 2 4 7 5 10 3 2 4 6 4 3 5 9 10 3 5 12 6 */
题目地址:C. 图像识别-计算机二2014
解题思路:
这个就是个dfs的题目,从一个点出发,可以把他周围的八个方向的点满足条件的都遍历了,如果可以他们就是一类,继续搜。
AC代码:
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #define maxn 105 using namespace std; int m,n,d; int a[maxn][maxn]; int vis[maxn][maxn]; int dir[8][2]= {{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}}; //八个方向 int ab(int p) { if(p<0) p=0-p; return p; } void dfs(int x,int y) { int i,cx,cy; for(i=0; i<8; i++) { cx=x+dir[i][0]; cy=y+dir[i][1]; if(cx>=0&&cx<m&&cy>=0&&cy<n&&!vis[cx][cy]&&ab(a[cx][cy]-a[x][y])<=d) //满足条件的点 { vis[cx][cy]=1; dfs(cx,cy); } } return; } int main() { int tes,i,j; while(~scanf("%d",&tes)) { while(tes--) { scanf("%d%d%d",&m,&n,&d); for(i=0; i<m; i++) { for(j=0; j<n; j++) { scanf("%d",&a[i][j]); vis[i][j]=0; } } int res=0; for(i=0; i<m; i++) { for(j=0; j<n; j++) { if(!vis[i][j]) { res++; vis[i][j]=1; dfs(i,j); } } } printf("%d\n",res); } } return 0; } /* 2 3 3 0 1 1 1 0 1 0 0 1 0 3 4 1 10 11 12 13 9 8 7 6 2 3 4 5 */
题目地址:D. 汇编-计算机二2014
解题思路:
先分析题目大意,总共有两种操作。
ADD
MOV
逗号之前是AX,AL,AH这个分三类讨论。我把AX,BX,CX,DX的值存到了一个数组里。分别对应a[0,1,2,3]
这样方便处理。
逗号之后需要分情况讨论,一种是AX,AL,AH这种。还有一种就是二进制,十六进制,十进制的数这种。把这个结果保存到tmp即可。详见代码。
AC代码:
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #define maxn 105 using namespace std; int m,n,d; int a[4]; char str[maxn]; char op[maxn]; int main() { int tes,n,i; while(~scanf("%d",&tes)) { while(tes--) { scanf("%d",&n); memset(a,0,sizeof(a)); while(n--) { scanf("%s",op); scanf("%s",str); int len=strlen(str); int t=str[0]-'A'; int tmp=0; if(str[len-1]=='X'||str[len-1]=='L'||(str[len-1]=='H'&&str[3]!='0')) { //<span style="font-family: Arial, Helvetica, sans-serif;">逗号之后的数如果是AX,AL,AH之类的</span> int t2=str[len-2]-'A'; if(str[len-1]=='X') tmp=a[t2]; else if(str[len-1]=='L') tmp=a[t2]%256; else tmp=a[t2]/256; } else //逗号之后的数如果是二进制,十进制,十六进制的 { int d; if(str[len-1]=='H') //十六进制 d=16; else if(str[len-1]=='B') //二进制 d=2; else //十进制 { len++; d=10; } int x; for(i=3; i<len-1; i++) { if(str[i]>='0'&&str[i]<='9') x=str[i]-'0'; else x=str[i]-'A'+10; tmp=tmp*d+x; } } if(strcmp(op,"MOV")==0) //如果是MOV { if(str[1]=='X') a[t]=tmp; else if(str[1]=='L') a[t]=a[t]/256*256+tmp; else a[t]=a[t]%256+tmp*256; } else //如果是ADD { if(str[1]=='X') a[t]+=tmp; else if(str[1]=='L') a[t]+=tmp; else a[t]=a[t]+tmp*256; } } printf("%d %d %d %d\n",a[0],a[1],a[2],a[3]); } } return 0; } /* 2 3 MOV AX,2 MOV BX,3 ADD AX,BX 5 MOV AX,2 MOV BX,030H MOV CX,11B ADD AX,CX ADD DL,CL */