西工大计算机复试机试2015+2016+2017篇

这几个系列里有重复的题我都没有做,每个题就出现一次,大家看完整个系列就OK。

补一句,2015年的题真的很顶。

西工大计算机复试2017篇

1.输入两组时间(h,m,s),计算平均时间。两组时间不超过一个小时,h在0-11之间

Input:
1 20 30 1 30 30
0 20 30 11 30 30
Output:
1 25 30
11 55 30

解析:注意这里有个坑,两组时间不超过一个小时,且j介于0-11之间,所以例二应该是11:30:30在前,0:20:30在后。此题不难,但需要思考出良好的解法才行,暴力解可行,但有点麻烦。

代码:

#include<iostream>
using namespace std;
int CalSec(int h1,int m1,int s1,int h2,int m2,int s2)
{
    return ((h1+h2)*3600+(m1+m2)*60+s2+s1)/2;
}
int main()
{
    int h1,m1,s1,h2,m2,s2;
    while(cin>>h1>>m1>>s1>>h2>>m2>>s2)
    {
        int sec=0;
        int m,s,h;
        if(h1==11&&h2==0)
        {
            sec+=CalSec(h1,m1,s1,12,m2,s2);
            h=sec/3600;
            m=(sec%3600)/60;
            s=(sec%3600)%60;
        }
        else if(h2==11&&h1==0)
        {
            sec+=CalSec(12,m1,s1,11,m2,s2);
            h=sec/3600;
            m=(sec%3600)/60;
            s=(sec%3600)%60;
        }
        else
        {
            sec+=CalSec(h1,m1,s1,h2,m2,s2);
            h=sec/3600;
            m=(sec%3600)/60;
            s=(sec%3600)%60;
        }
        if(h==12)
           h=0;
        cout<<h<<"  ";
        cout<<m<<"  ";
        cout<<s<<endl;
    }
    return 0;
}

2.输入行数,再在每行输入一个表达式,得出结果

Input:
3
1+1
2.2/3
1+2*3+2
 
Output:
2
0.7
9

解析:此处这个题没有涉及到括号,所以不难,可以不用数据结构解开。我会补一篇包含括号的,用要到栈和队列。

代码:

#include<iostream>
#include<stdio.h>
using namespace std;

int main()
{
    int n;
    cin>>n;
    while(n--)
    {
        double a[20];
        double sum=0;
        cin>>a[0];
        char c;
        c=getchar();
        int i=0;
        while(c!='\n')
        {
            double tmp;
            cin>>tmp;
            switch(c)
            {
                case '+':a[++i]=tmp;break;
                case '-':a[++i]=-tmp;break;
                case '*':a[i]*=tmp;break;
                case '/':a[i]/=tmp;break;
            }
            c=getchar();
        }
        for(int j=0;j<=i;j++)
            sum=sum+a[j];
        if(sum-int(sum)<=1e-6)
            printf("%.0f\n",sum);
        else
            printf("%.1lf\n",sum);
    }
    return 0;
}

西工大计算机复试2016篇

1.小王围操场跑圈,每次跑三圈,请输入行数,每行输入九个整数,表示每圈所用的分,秒和毫秒。输出每次跑步所用的平均时间。

输入示例:
2
1 10 100 1 20 100 1 30 100
2 10 100 1 20 100 1 30 100

输出示例:
1 20 100
1 40 100

解析:沿用一贯做法,加和再做平均数。

代码:

#include<iostream>
#include<stdio.h>
using namespace std;
struct TNode{
   int m;
   int s;
   int ms;
};
int main()
{
    int n;
    cin>>n;
    while(n--)
    {
        struct TNode t1,t2,t3;
        cin>>t1.m>>t1.s>>t1.ms;
        cin>>t2.m>>t2.s>>t2.ms;
        cin>>t3.m>>t3.s>>t3.ms;
        int em,es,ems;
        int sum=0;
        sum+=(t1.m+t2.m+t3.m)*60*1000+(t1.s+t2.s+t3.s)*1000+t1.ms+t2.ms+t3.ms;
        sum=sum/3;
        em=sum/60000;
        es=(sum%60000)/1000;
        ems=(sum%60000)%1000;
        cout<<em<<" ";
        cout<<es<<" ";
        cout<<ems<<endl;
    }
    return 0;
}

西工大计算机复试2015篇

1.求最小数,给定三个数(int型),输出最小的数

Input:
5 2 55
output:
2

2.十进制转换为二进制

input:
1030
otput:
10000000110

解析:上两题过于简单,不做。

3.计算单词个数:给一行句子,写一个程序判断它有几个单词。

输入占一行,只包含大小写字母和空格,输出单词的个数。
输入样例:
genaral game players are systems to

输出样例:
7

解析:注意想清楚各种情况,如最后一个字符是单词或者空格或者连几个空格。

代码:

#include<iostream>
#include<stdio.h>
using namespace std;
int main()
{
    int num=0;
    string str;
    int i;
    getline(cin,str);
    int len=str.size();
    for(i=0;i<len;i++)
    {
        if(str[i]!=' ')
            break;
    }
    for(;i<len-1;i++)
    {
        if(str[i]==' '&&str[i+1]!=' ')
            num++;
    }
    if(str[len-1]!=' ')
        num++;
    if(str[len-1]==' '&&str[len-2]!=' ')
        num++;
    cout<<num<<endl;
    return 0;
}

4.字符串替换问题:输入三个字符串a,b和c,将a中第一次出现b的地方替换为c

输入样例
abcdefg
cde
xiaolan

输出样例
abxiaolanfg

解析:此题可以用字符数组解决,但比较麻烦,此处介绍replace函数,可直接使用。(C++永远的神)

代码:

#include<iostream>
#include<string>
using namespace std;
int main()
{
    string s[3];
    for(int i=0;i<3;i++)
        getline(cin,s[i]);
    int pos=s[0].find(s[1]);
    s[0]=s[0].replace(pos,s[1].size(),s[2]);
    cout<<s[0]<<endl;
    return 0;
}

5.迷宫问题

6.迷宫问题2

解析:这两个题看着很吓人,,,,其实很简单,判断一下要走位置是不是墙即可,所以不做。下面附一个走迷宫问题,使用广搜,比较有参考价值。

8.连阴雨问题:因为下雨,地上有很多水,W代表积水,.代表干燥,我们将“相邻”定位为八个方向,相邻的积水构成一个水坑,先输入M,N,再输入一个M行N列字符矩阵,输出互不相邻的水坑个数。

输入样例:
10 12
W........WW.
.WWW.....WWW
....WW...WW.
.........WW.
.........W..
..W......W..
.W.W.....WW.
W.W.W.....W.
.W.W......W.
..W.......W.

输出样例:
3

解析:说一下思路。挨个判断,对于每个,判断其周围的八个位置有没有水,若有进一步判断这个水是不是被用过,若没用过,水坑数加一,used数组置为1即可,并且周围的水也都置为1。

代码:

#include<iostream>
#include<string>
#include<stdio.h>
using namespace std;
int main()
{
    int dirx[8]={-1,0,1,1,1,0,-1,-1};
    int diry[8]={1,1,1,0,-1,-1,-1,0};
    int m,n;
    int a[20][20],used[20][20]={0};
    cin>>m>>n;
    int num=0;
    getchar();
    char c;
    for(int i=0;i<m;i++)
    {
        for(int j=0;j<n;j++)
        {
            c=getchar();
            if(c=='W')
                a[i][j]=0;//积水
            else
                a[i][j]=1;//干燥
        }
        getchar();
    }
    for(int i=0;i<m;i++)
    {
        for(int j=0;j<n;j++)
        {
            if(a[i][j]==0)//对于每个水坑
            {
                int flag=0;
                for(int k=0;k<8;k++)
                {//判断八个方位是否有水
                    int x=i+dirx[k];
                    int y=j+diry[k];
                    if(x>=0&&x<=m&&y>=0&&y<=n)//方位是否合法
                    {
                        if(used[x][y]==1&&a[x][y]==0)//一旦有一个用过的水坑
                        {
                            flag=1;
                            break;
                        }
                    }
                }
                //被用过,则周围的水坑都used置为1,num不加
                //若没用过,同样置为1,但num++
                if(flag==0)
                    num++;
                used[i][j]=1;
                for(int k=0;k<8;k++)
                {
                    int x=i+dirx[k];
                    int y=j+diry[k];
                    if(x>=0&&x<=m&&y>=0&&y<=n)
                        if(used[x][y]==0&&a[x][y]==0)
                            used[x][y]=1;
                }
            }
        }
    }
    cout<<num<<endl;
    return 0;
}

7.六数码问题:

现有一两行三列的表格如下:
A B C
D E F
把1、2、3、4、5、6六个数字分别填入A、B、C、D、E、F格子中,每个格子一个数字且各不相同。每种不同的填法称为一种布局。如下:
布局1:1 3 5
             2 4 6
布局2:2 5 6
             4 3 1
定义α变换如下:把A格中的数字放入B格,把B格中的数字放入E格,把E格中的数字放入D格,把D格中的数字放入A格。
定义β变换如下:把B格中的数字放入C格,把C格中的数字放入F格,把F格中的数字放入E格,把E格中的数字放入B格。

问:对于给定的布局,可否通过有限次的α变换和β变换变成下面的目标布局:
目标布局:1 2 3
                  4 5 6

输入

本题有多个测例,每行一个,以EOF为输入结束标志。每个测例的输入是1到6这六个数字的一个排列,空格隔开,表示初始布局ABCDEF格中依次填入的数字。

输出
每个输出占一行。可以转换的,打印Yes;不可以转换的,打印No。


输入样例
1 3 5 2 4 6
2 5 6 4 3 1


输出样例
No
Yes

解析:此题较难,需要用到广搜和队列解决的问题。建议去看一下博主写的算法设计与分析篇的所有文章,虽然可能难度大于机试,但涵盖了所有算法,如分支限界法、回溯法、动态规划等所有高明的算法。下面解析一下本题。

对于输入的序列,可使用一维或者二维数组存下来,以便于后边bfs(广搜函数)在遍历到下一个状态时,用来比较这个状态是否早已经到达。此处我用一维数组存,以便使用map函数。进入bfs后,每次取出队列首的序列,进行两个不同的转换,即α和β变换,变换在外边写函数实现,不要冗杂在bfs里。将变换所得状态入队列,并且步数加一。当然入队列之前检查这一步是否早已被到达,要是早已到达就不用入队列了(早到了你现在才到,当然选步数早的到法),不然就不满足广搜最优性质了。

然后重点来了,那么我们怎么检查当然的状态是否已经用过了呢?队列里的每一步的状态是边用边离开的,以前的状态都没有保存下来,所以我们没办法遍历队列进行比较看是否它用过了。那么这里我们有两种解决办法,第一种是利用C++自带的map函数,可以自带查重的功能,这个大家可以自行查询。第二种是自己的土方法,就是从队列刚开始工作时,就把每一步的状态都存到一个二维数组里,以后的新状态都遍历这个二维数组进行查重。这两种方法都是行得通的。

大概如此,至于更为详尽的解析,参考另一篇博主的:https://mp.csdn.net/editor/html/86256433

代码:

#include<iostream>
#include<string>
#include<map>
#include<queue>
using namespace std;
map<int,int>used;
queue<int>q;
int m[7]={0};
int num=0;
void Readdata()
{
    num=0;
    for(int i=0;i<6;i++)
    {
        cin>>m[i];
        num=num*10+m[i];
    }
}
void Initdata()
{
    while(!q.empty())//清空队列
        q.pop();
    used.clear();//清空map
    used[num]=1;//或者used.insert(map<int,int>(num,1)))
    q.push(num);//将输入数字入队列和map
}
int Move(int cur,int i)
{
    int res=0;
    for(int j=5;j>=0;j--)
    {
        m[j]=cur%10;
        cur=cur/10;
    }
    int a,b,c,d,e,f;
    if(i==0)
    {
        a=m[0];
        b=m[1];
        d=m[3];
        e=m[4];
        m[1]=a;
        m[4]=b;
        m[3]=e;
        m[0]=d;
    }
    else
    {
        b=m[1];
        c=m[2];
        e=m[4];
        f=m[5];
        m[2]=b;
        m[5]=c;
        m[4]=f;
        m[1]=e;
    }
    for(int j=0;j<6;j++)
        res=res*10+m[j];
    return res;
}
int bfs()
{
    //队列为空为截至条件,要是还是到不了说明无法到达
    while(!q.empty())//队列为空为截至条件
    {
        int cur=q.front();
        q.pop();//取出队列首元素
        for(int i=0;i<2;i++)
        {
            int v=Move(cur,i);//分别进行两次转换
            if(v==123456)
                return 1;
            else if(used[v]==0)
            {
                q.push(v);
                used[v]=1;
            }
        }
    }
    return 0;
}
int main()
{
    while(1)
    {
        Readdata();
        Initdata();
        if(bfs())
            cout<<"Yes"<<endl;
        else
            cout<<"No"<<endl;
    }

    return 0;
}

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值