2017年 中南大学研究生复试机试题 (1020~1024)

目录:

A:切木棍
B:机器人走迷宫
C:淘金
D:巨人排队

A:切木棍

http://39.106.164.46/problem.php?id=1020

思路:
白给题目。
AC代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX 35
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;

int n;

int main(){
    while(scanf("%d",&n)!=EOF){
        if(n%2==1) printf("0\n");
        else printf("%d\n",(n/2-1)/2);
    }
    return 0;
}

B:机器人走迷宫

http://39.106.164.46/problem.php?id=1021

思路:
dfs模拟机器人的行走命令。
AC代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX 15
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;

int n,m,vis[MAX][MAX],ans;
char mp[MAX][MAX],command;
int dir[4][2]={{0,-1},{0,1},{1,0},{-1,0}};

struct node{
    int x,y;
    node(int xx,int yy){
        x=xx;
        y=yy;
    }
};

bool judge(int x,int y){
    if(x<1||x>n||y<1||y>m) return false;
    return true;
}

void dfs(int x,int y,char command){
    vis[x][y]=1;
    ans++;
    int i;
    if(command=='L') i=0;
    if(command=='R') i=1;
    if(command=='U') i=3;
    if(command=='D') i=2;
    int xx=x+dir[i][0],yy=y+dir[i][1];
    if(judge(xx,yy)==false||vis[xx][yy]==1||mp[xx][yy]=='*'){
        if(command=='L') {i=3;command='U';}
        else if(command=='U') {i=1;command='R';}
        else if(command=='R') {i=2;command='D';}
        else if(command=='D') {i=0;command='L';}
    }
    xx=x+dir[i][0],yy=y+dir[i][1];
    if(judge(xx,yy)&&vis[xx][yy]==0&&mp[xx][yy]!='*'){
        dfs(xx,yy,command);
    }
}

int main(){
    while(scanf("%d %d",&n,&m)!=EOF){
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++){
            scanf("%s",mp[i]+1);
        }
        int x,y;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(mp[i][j]!='.'&&mp[i][j]!='*'){
                    x=i,y=j;
                    command=mp[i][j];
                }
            }
        }
        ans=0;
        dfs(x,y,command);
        printf("%d\n",ans);
    }
    return 0;
}

C:淘金

http://39.106.164.46/problem.php?id=1022

思路:
动态规划题目,分为两次dp:
第一次对每行的元素进行dp,求出每行可以取得的最大值dp2[i],dp2[i]表示第i行可以得到的最大值;
第二次对所有行进行dp,筛选出最优的所有行
AC代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX 205
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;

int n,m,mp[MAX][MAX];
int dp1[MAX],dp2[MAX],res[MAX];

int main(){
    while(scanf("%d %d",&n,&m)!=EOF){
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                scanf("%d",&mp[i][j]);
            }
        }
        for(int i=0;i<n;i++){
            dp1[0]=mp[i][0];
            dp1[1]=max(mp[i][0],mp[i][1]);
            for(int j=2;j<m;j++){
                dp1[j]=max(dp1[j-1],dp1[j-2]+mp[i][j]);
            }
            dp2[i]=dp1[m-1];
        }
        res[0]=dp2[0];
        res[1]=max(dp2[0],dp2[1]);
        for(int i=2;i<n;i++){
            res[i]=max(res[i-1],res[i-2]+dp2[i]);
        }
        printf("%d\n",res[n-1]);
    }
    return 0;
}

D:巨人排队

http://39.106.164.46/problem.php?id=1023

思路:
贪心,即对于每个学生的身高,都在队伍中找大于等于此身高且最小的那名学生,将本学生放在其后面。但O(n2)肯定是会超时的。其实每个队伍的队尾是按照身高增序排列的,我们可以在这里使用二分法降低时间复杂度。
AC代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX 100005
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;

int n,a[MAX],b[MAX];

int main(){
    while(scanf("%d",&n)!=EOF){
        for(int i=0;i<n;i++){
            scanf("%d",&a[i]);
        }
        int cnt=0;
        for(int i=0;i<n;i++){
            if(i==0||b[cnt-1]<a[i]) b[cnt++]=a[i];
            else{
                int pos=lower_bound(b,b+cnt,a[i])-b;
                b[pos]=a[i];
            }
        }
        printf("%d\n",cnt);
    }
    return 0;
}

E:走路还是坐公交

http://39.106.164.46/problem.php?id=1024

思路:
bfs。因为每次移动的代价是相同的,所以可以将每次到达的坐标看成一个节点,每次可以-1,+1或者*2,也就是可以看成一个三叉树,然后从根节点进行搜索。
AC代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX 100005
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;

int n,k,vis[MAX],dis[MAX];

void bfs(){
    memset(vis,0,sizeof(vis));
    memset(dis,0,sizeof(dis));
    queue<int> q;
    q.push(n);
    vis[n]=1;
    dis[n]=0;
    while(!q.empty()){
        int top=q.front();
        q.pop();
        if(top==k){
            printf("%d\n",dis[top]);
            break;
        }
        int tmp=top-1;//坐标后退一步
        if(tmp>=0&&vis[tmp]==0){
            vis[tmp]=1;
            dis[tmp]=dis[top]+1;//深度加1
            q.push(tmp);
        }
        tmp=top+1;//坐标前进一步
        if(tmp<=100000&&vis[tmp]==0){
            vis[tmp]=1;
            dis[tmp]=dis[top]+1;
            q.push(tmp);
        }
        tmp=top*2;
        if(tmp<=100000&&vis[tmp]==0){//坐标乘以2
            vis[tmp]=1;
            dis[tmp]=dis[top]+1;
            q.push(tmp);
        }
    }
}

int main(){
    while(scanf("%d %d",&n,&k)!=EOF){
        bfs();
    }
    return 0;
}

你可能感兴趣的:(机试)