bistuacm 2019年第⑦场新生训练赛题解

比赛链接:bistuacm 新生训练赛 第七场
难度:cf 900~1400

A

知识点:枚举
题意:寻找距离数组某个数最接近的a[i]<=k且b[i]=1的数。
解法:按题意模拟即可。

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n,m,k;
    cin>>n>>m>>k;
    m--;
    int a[222],b[222];
    int i,t;
    for(i=0;i<n;i++){
        cin>>a[i];
    }
    for(t=0;;t++){
        int x=m+t,y=m-t;
        if(y>=0)if(a[y]&&a[y]<=k)break;
        if(x<=n-1)if(a[x]&&a[x]<=k)break;
    }
    cout<<10*t;
}

B

知识点:数学
题意:找到大于a,且各数位只含一个非0数字的数,输出其和a的差。
解法:求出a的最高位和a的位数,(a的最高位+1)*10^(位数-1)即为所求数,求差即可。

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n,m=1,k;
    cin>>n;
    k=n;
    while(n>=10){
        n/=10,m*=10;
    }
    if(k==n*m)cout<<m;
    else cout<<(n+1)*m-k;
}

C

知识点:字符串
题意:一个字符串,若某字符不是最后一次出现,则需要占用一个空间。若出现了最后一次之后则释放空间。问至少需要多少空间。
解法:先预处理一遍每个字符出现的最后位置,然后按题意模拟即可。

#include<bits/stdc++.h>
using namespace std;
char a[1111111];
int main(){
    int n,i,k;
    int ma[26];
    for(i=0;i<26;i++)ma[26]=0;
    cin>>n>>k;
    int m=0;
    cin>>a;
    for(i=0;a[i]!='\0';i++){
        ma[a[i]-'A']=i;
    }
    int tong[26]={0},cnt=0;
    for(i=0;a[i]!='\0';i++){
        if(!tong[a[i]-'A'])tong[a[i]-'A']++,cnt++;
        m=max(m,cnt);
        if(tong[a[i]-'A']&&i==ma[a[i]-'A'])cnt--;
    }
    if(m>k)cout<<"YES";
    else cout<<"NO";
}

D

知识点:博弈
题意:给定一数组。A每次可以取和为奇数的连续段,B每次可以取和为偶数的连续段。两人轮流取,先取不了的人输。问最优策略下谁赢。
解法:若sum为奇数,A直接获胜。
若sum为偶数,假设存在某奇数,显然A取完之后总和变成奇数,之后B无论取不取都是A获胜。
若不存在奇数,则A取不了,B获胜。

#include<bits/stdc++.h>
using namespace std;

int main(){
    int n,i;
    long long jud=0,sum=0;
    cin>>n;
    while(n--){
        long long x;
        cin>>x;
        sum+=x;
        if(x&1)jud=1;
    }
    if(sum&1)cout<<"First";
    else if(!jud)cout<<"Second";
    else cout<<"First";
}

E

知识点:贪心
题意:每一次可以进新房间或旧房间(要求是上一次走过的)。问房间最小值。
解法:显然不可能有两次上一次“同一时间”走到旧房间。因此遇到相同的数则新房间数加一即可。要注意的是t0为0的时候已经有一个房间,因此遇到0的时候一定有新房间。

#include<bits/stdc++.h>
using namespace std;
int a[222222];
int main(){
    int n,i;
    cin>>n;
    for(i=0;i<n;i++)cin>>a[i];
    sort(a,a+n);
    int cnt=0;
    for(i=0;i<n-1;i++)cnt+=a[i]==0?1:a[i]==a[i+1];
    cout<<cnt+(!a[i]);
}

F

知识点:排序/map
题意:a数组有一些数。现给定两个数组b[m]和c[m],求某个i使b[i]在a中出现次数最多。若有多个最多的b[i],则需要让c[i]最多。
解法:用一个map存a中每个数出现的次数,然后可直接找出对应b[i]和c[i]在a中的出现次数。

#include<bits/stdc++.h>
using namespace std;
struct mov{
    int b,c;
};
int a[222222];
mov m[222222];
map<int,int>M;
map<int,int>::iterator it1,it2;
bool f(int i,int j){
    it1=M.find(m[i].b);
    it2=M.find(m[j].b);
    if(it1==M.end())return 1;
    if(it2==M.end())return 0;
    if(it1->second!=it2->second)return it1->second<it2->second;
    else{
        it1=M.find(m[i].c);
        it2=M.find(m[j].c);
        if(it1==M.end())return 1;
        if(it2==M.end())return 0;
        return it1->second<it2->second;
    }
}
int main(){
    int n,i;
    cin>>n;
    for(i=0;i<n;i++)cin>>a[i];
    int t;
    cin>>t;
    for(i=0;i<t;i++)cin>>m[i].b;
    for(i=0;i<t;i++)cin>>m[i].c;
    sort(a,a+n);
    int cnt=1,mm=1;

    for(i=0;i<n-1;i++){
        if(a[i]==a[i+1])cnt++;
        else M[a[i]]=cnt,cnt=1;
    }
    M[a[i]]=cnt;

    int m=0;
    for(i=1;i<t;i++){
        if(f(m,i))m=i;
    }
    cout<<m+1;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值