2016年中南大学研究生复试机试题(1015~1019)

目录:

**A:第几天
B:加油站
C:序列求平均
D:士兵排阵
**

A:第几天

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

思路:
分闰年和非闰年讨论即可。

AC代码:

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

string s;
map<int,int> mp;

int main(){
    mp[1]=31,mp[2]=28,mp[3]=31,mp[4]=30,mp[5]=31;
    mp[6]=30,mp[7]=31,mp[8]=31,mp[9]=30,mp[10]=31;
    mp[11]=30,mp[12]=31;
    while(cin>>s){
        int y=0,m=0,d=0,cnt=0,tmp=0;
        for(int i=0;i<s.length();i++){
            if(s[i]>='0'&&s[i]<='9') tmp=tmp*10+s[i]-'0';
            else{
                if(cnt==0){
                    cnt++;
                    y=tmp;
                    tmp=0;
                }else if(cnt==1){
                    cnt++;
                    m=tmp;
                    tmp=0;
                }
            }
        }
        d=tmp;
        bool flag=false;
        if(y%400==0) flag=true;
        if(y%4==0&&y%100!=0) flag=true;
        if(flag==true){
            mp[2]=29;
        }
        int ans=0;
        for(int i=1;i<m;i++){
            ans+=mp[i];
        }
        ans+=d;
        mp[2]=28;
        printf("%d\n",ans);
    }
    return 0;
}

B:加油站

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

思路:
贪心模板题。

AC代码:

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

int n,k,dis[MAX];

int main(){
    while(cin>>n>>k){
        int sum=0;
        for(int i=1;i<=k+1;i++){
            cin>>dis[i];
            sum+=dis[i];
        }
        int cnt=0,now=0,id=1;
        if(n<dis[1]){printf("NoSolution\n");continue;}
        bool flag=true;
        while(now<sum){
            int tmp=0;
            if(n<dis[id]&&now<sum){
                flag=false;
                break;
            }
            while(tmp+dis[id]<=n){
                tmp+=dis[id++];
            }
            now+=tmp;
            cnt++;
        }
        if(flag) printf("%d\n",cnt-1);
        else printf("NoSolution\n");
    }
    return 0;
}

C:序列求平均

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

思路:
vector模拟一下即可。
AC代码:

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

int n,m;

int main(){
    while(cin>>n>>m){
        vector<int> vec,res;
        for(int i=1;i<=n;i++) vec.push_back(i*2);
        int cnt=0,tmp=0;
        for(int i=0;i<vec.size();i++){
            tmp+=vec[i];
            cnt++;
            if(cnt==m){
                res.push_back(tmp/m);
                cnt=0;
                tmp=0;
            }
        }
        if(cnt!=0) res.push_back(tmp/cnt);
        for(int i=0;i<res.size();i++){
            printf("%d ",res[i]);
        }
        printf("\n");
    }
    return 0;
}

D:士兵排阵

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

思路:
假设每个点的坐标为(X1, Y1), (X2, Y2), …, (Xn-1, Yn-1), (Xn, Yn)。在x方向和y方向上将坐标分别排序,对于Y方向,假设最终所有士兵的坐标为Y,即求|Y1-Y| + |Y2-Y| + … + |Yn-1-Y| + |Yn-Y|的最小值,可以证明Y其实是Y1,Y2…Yn的中位数。对于x方向,假设最后所有士兵的位置为(X, X+1, X+2, …, X+n-1),通过上面的解释,我们令X1->X, X2->X+1, …, Xn-1->X+n-2, Xn->X+n-1,这样不会产生碰撞。那么我们求的就是|X1-X| + |X2-(X+1)| + … + |Xn-1-(X+n-2)| + |Xn-(X+n-1)|的最小值,将该式变换,得|X1-X| + |(X2-1)-X| + … + |[Xn-1-(n-2)]-X| + |[Xn-(n-1)]-X|的最小值,要使该式子最小,即X为X1, X2-1, …, Xn-1-(n-2), Xn-(n-1)的中位数,于是可以把X[i]都减去(i-1),找出中位数,计算最小步数。
AC代码:

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

int n,x[MAX],y[MAX];

int main(){
    while(cin>>n){
        for(int i=0;i<n;i++){
            cin>>x[i]>>y[i];
        }
        sort(x,x+n);
        for(int i=0;i<n;i++) x[i]-=i;
        sort(x,x+n);
        sort(y,y+n);
        int midx=x[n/2],midy=y[n/2];
        int cnt=0;
        for(int i=0;i<n;i++){
            cnt+=abs(x[i]-midx);
            cnt+=abs(y[i]-midy);
        }
        cout<<cnt<<endl;
    }
    return 0;
}

E:堆石子

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

思路:
区间dp。可以参考:
https://blog.csdn.net/weixin_44123362/article/details/102704895
AC代码:

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

int n,a[MAX],sum[MAX],dp[MAX][MAX];

int d(int i,int j){ //计算合并i~j的代价
    return sum[j]-sum[i-1];
}

int main(){
    while(cin>>n){
        for(int i=1;i<=n;i++){
            cin>>a[i];
            sum[i]=sum[i-1]+a[i];
        }
        for(int l=1;l<n;l++){
            for(int i=1,j=i+l;i<=n&&j<=n;i++,j=i+l){
                dp[i][j]=INF;
                for(int k=i;k<j;k++){
                    dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+d(i,j));
                }
            }
        }
        cout<<dp[1][n]<<endl;
    }
    return 0;
}

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