2020 中南大学研究生招生夏令营机试题(1252~1256)

A:缺失的彩虹

http://39.106.164.46/problem.php?id=1252
思路:
使用map即可。
AC代码:

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

int n,flag[10];
string s[MAX];
map<string,int> mp;


int main(){
    mp["red"]=0;mp["orange"]=1;mp["yellow"]=2;
    mp["green"]=3;mp["cyan"]=4;mp["blue"]=5;mp["purple"]=6;
    while(cin>>n){
        memset(flag,0,sizeof(flag));
        for(int i=0;i<n;i++){
            cin>>s[i];
            flag[mp[s[i]]]=1;
        }
        int cnt=0;
        for(int i=0;i<7;i++){
            if(flag[i]==0) cnt++;
        }
        cout<<cnt<<endl;
         for(int i=0;i<7;i++){
            if(flag[i]==0){
                if(i==0) cout<<"A"<<endl;
                else if(i==1) cout<<"B"<<endl;
                else if(i==2) cout<<"C"<<endl;
                else if(i==3) cout<<"D"<<endl;
                else if(i==4) cout<<"E"<<endl;
                else if(i==5) cout<<"F"<<endl;
                else if(i==6) cout<<"G"<<endl;
            }
        }
    }
    return 0;
}

B:最小价值和

http://39.106.164.46/problem.php?id=1253
思路:
此题是比较两个数对间的“大小关系”。
2020 中南大学研究生招生夏令营机试题(1252~1256)_第1张图片
也就是说,若交换前的价值大于交换后的价值,就需要a1-b1,反过来,我们是要总价值最小,所以把a-b大的排在前面即可。
AC代码:

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

int n;

struct node{
    int fir,sec;
    bool operator < (const node &a) const{
        return fir-sec>a.fir-a.sec;
    }
    node(int f,int s){
        fir=f;
        sec=s;
    }
};

vector<node> vec;

int main(){
    int f,s;
    while(scanf("%d",&n)!=EOF){
        for(int i=0;i<n;i++){
            scanf("%d %d",&f,&s);
            vec.push_back(node(f,s));
        }
        sort(vec.begin(),vec.end());
        ll res=0;
        for(int i=0;i<n;i++){
            int j=i+1;
            res+=ll(j-1)*vec[i].fir+ll(n-j)*vec[i].sec;
        }
        printf("%lld\n",res);
        vec.clear();
    }

    return 0;
}

C:PIPI上学路

http://39.106.164.46/problem.php?id=1254
思路:
简单的dp。
每个格子可以由左边的格子或者右边的格子到达,那么很容易写出递推式:
dp[i][j] = (dp[i-1][j] + dp[i][j-1]) %mod
由于题目是从(x1,y1)到达(x2,y2),我们将(x1,y1)平移到左上角,(x2,y2)平移相同的距离,即dp[x2-(x1-1)][y2-(y1-1)]就是最终答案。

代码如下:

#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,q,dp[MAX][MAX];
int x1,x2,y_1,y2;
int mod=1e9+7;

int main(){
    memset(dp,0,sizeof(dp));
    for(int i=1;i<MAX;i++) dp[i][1]=1;
    for(int j=1;j<MAX;j++) dp[1][j]=1;
    for(int i=2;i<MAX;i++){
        for(int j=2;j<MAX;j++){
            dp[i][j]=(dp[i-1][j]+dp[i][j-1])%mod;
        }
    }

    while(scanf("%d %d %d",&n,&m,&q)!=EOF){
        for(int i=0;i<q;i++){
            scanf("%d %d %d %d",&x1,&y_1,&x2,&y2);
            x2=x2-x1+1,y2=y2-y_1+1;
            printf("%d\n",dp[x2][y2]);
        }
    }
    return 0;
}

D:最大容量和

http://39.106.164.46/problem.php?id=1255
思路:
如果不考虑L的限制,我们需要让桶最短的那根木棍尽可能长,那么可以将木棍的长度从小到大排序,从大的往小的依次选择,当每有k根木棍时,就组成一个桶;如果考虑L的限制,由于所有木棍最短的那根一定决定了最小容量,因此,我们只要最大的桶的最短的那根木棍长度小于等于a[0]+l即可。

代码如下:

#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,l,m,a[MAX];

int main(){
    scanf("%d %d %d",&n,&k,&l);
    m=n*k;
    for(int i=0;i<m;i++){
        scanf("%d",&a[i]);
    }
    sort(a,a+m);
    int max_pos=upper_bound(a,a+m,a[0]+l)-a;
    ll ans=0;
    int cnt=0;
    for(int i=m-1;i>=0;i--){
        cnt++;
        if(i<max_pos&&cnt>=k){
            cnt-=k;
            ans+=a[i];
        }
    }
    if(cnt>0) printf("0\n"); //说明还有木棍没用上,那么就不能组成n个桶了
    else printf("%lld\n", ans);
    return 0;
}

E:最小特征值

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

代码如下:

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

int n,c,a[MAX];
ll dp[MAX];

int main(){
    ll sum=0;
    multiset<int> s; //可重集
    scanf("%d %d",&n,&c);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        sum+=a[i];
    }
    for(int i=1;i<=n;i++){
        dp[i]=dp[i-1];
        s.insert(a[i]);
        if(i>c) s.erase(s.find(a[i-c]));
        if(i>=c) dp[i]=max(dp[i],dp[i-c]+(*s.begin()));
    }
    printf("%lld",sum-dp[n]);
    return 0;
}

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