FYN OI奋斗之路9~

XJOI 奋斗群群赛 14 解题报告

原题

https://cn.vjudge.net/contest/186844 (Codeforces Round #386 (Div. 2))

A - Compote

题意

给出三个数表示柠檬,苹果和梨的个数,做一个蛋糕需要1个柠檬,2个苹果,4个梨,问最多能做几个蛋糕.

题解

柠檬个数不变,苹果个数除以2,梨个数除以4,输出三个数最小的.

#include<bits/stdc++.h>
using namespace std;
int main(){
    int a,b,c;
    cin>>a>>b>>c;
    b=b/2;
    c=c/4;
    int m=0;
    m=min(a,b);
    m=min(m,c);
    cout<<m*7;
}

B - Decoding

题意

有一种编码规则,给出一串字符串,如果长度为奇数,取最中间的放在生成串的下一个位置,否则把(中间-1)的放在生成串的下一个位置,重复该步骤.现给出一串用这种方法处理的字符串,让你求原字符串.

题解

逆着推回去,分类讨论一下,字符串长度是奇数,将第一位放在最中间,之后分第奇数个,第偶数个分别向前向后放,偶数的一样,将前两位放在中间即可.

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n,num,temp1=1,temp2=1;
    cin>>n;
    char c,ans[2010];
    if(n%2==1){
        num=n/2+1;
    }
    else num=n/2;
    for(int i=1;i<=n;i++){
        cin>>c;
        if(n%2==1){
        if(i==1) ans[num]=c;
        else if(i%2==1)  {
                ans[temp1+num]=c;
                temp1++;
            }
        else{
                ans[num-temp2]=c;
                temp2++;
        }
        }
        else{
            if(i==1)ans[num]=c;
            else if(i==2) ans[num+1]=c;
            else if(i%2==0){
                ans[temp1+num+1]=c;
                temp1++;
            }
            else{
                ans[num-temp2]=c;
                temp2++;
            }
        }
    }
    for(int i=1;i<=n;i++){
        cout<<ans[i];
    }
}

C - Tram

题意

有一辆电车在0-s的路上开,方向表示为d(从0到s或从s到0),开到终点后转向,每t1秒前进一米,初始位置为p,有一个人要从x1走向x2,每t2秒前进一米,这个人可以乘车前进,问到达x2的最短时间

题解

我们可以这样想:无论这个人中间上下车多少次,最终到达终点只有两种可能:走路到达,乘车到达,并且由于车速一定快,他一旦开始乘车,乘车到终点会比走路快,因此我们只要求出人步行到达终点的时间和车开到终点的时间后比较即可.

#include<bits/stdc++.h>
using namespace std;
int s,x1,x2,t1,t2,p,d;
int time0=0,dis=0,flag1=0,flag2=0;
int main(){ 
    scanf("%d %d %d %d %d %d %d",&s,&x1,&x2,&t1,&t2,&p,&d);
    if(x1>x2) flag1=1;
    if(d==-1) flag2=1;
    time0=abs(x2-x1)*t2;
    if(x1==x2){
        cout<<0;
        return 0;
    }
    if(t2<=t1){
        cout<<time0;
        return 0;
    }
    if(flag1==1&&flag2==1){
        if(p<x1){
            t1=(2*s+p-x2)*t1;
        }
        else{
            t1=(p-x2)*t1;
        }
    }
    if(flag1==0&&flag2==0){
        if(p<=x1){
            t1=(x2-p)*t1;
        }
        else{       
            t1=(2*s+x2-p)*t1;
        }
    }
    if(flag1==1&&flag2==0){
        t1=(2*s-p-x2)*t1;
    }
    if(flag1==0&&flag2==1){
        t1=(p+x2)*t1;
    }
    cout<<min(t1,time0);
    return 0;
}

D - Green and Black Tea

题意

一个人有n杯茶,a杯绿茶,b杯红茶,他不能连续喝k杯茶以上,问喝茶方案.

题解

对于a,b,如果a=b,那么交替喝直到喝完即可,否则,从大的喝起,大的喝k杯,小的喝一杯,这样操作的话问题会逐渐趋向a=b的情况,如果发现按照这种做法时应该喝某种茶了可茶的数量却为0,输出”NO”;

#include <bits/stdc++.h>
using namespace std;
const int MAXN=100010;
typedef long long int ll;
char s[MAXN];
int main() {
    int n, k, a, b, p = 0, i;
    scanf("%d %d %d %d", &n, &k, &a, &b);
    bool flag = 1, c;
    if(a>b) {
        int tmp = min(k, a-b);
        for(i = 1; i <= tmp; i++) {
            a--;
            s[p++] = 'G';
        }
        c = 0;
    } else if(b>a) {
        int tmp = min(k, b-a);
        for(i = 1; i <= tmp; i++) {
            b--;
            s[p++] = 'B';
        }
        c = 1;
    } else {
        for(i = 1; i <= a*2; i++) s[p++] = ((i%2==1)?'G':'B');
        a = b = 0;
    }
    while(a||b) {
        if(a==b) {
            if(c) for(i = 1; i <= a*2; i++) s[p++] = ((i%2==1)?'G':'B');
            else  for(i = 1; i <= a*2; i++) s[p++] = ((i%2==1)?'B':'G');
            break;
        }
        if(c) {
            if(a==0) {
                flag = 0;
                break;
            }
            a--;
            s[p++] = 'G';
            int tmp = min(k, b-a);
            for(i = 1; i <= tmp; i++) {
                b--;
                s[p++] = 'B';
            }
            c = 1;
        } else {
            if(b==0) {
                flag = 0;
                break;
            }
            b--;
            s[p++] = 'B';
            int tmp = min(k, a-b);
            for(i = 1; i <= tmp; i++) {
                a--;
                s[p++] = 'G';
            }
            c = 0;
        }
    }
    if(!flag) printf("NO\n");
    else {
        s[p] = '\0';
        printf("%s\n", s);
    }
}

E - Numbers Exchange

题意

一个人有n张牌,值为a1-an,另一个人有m张牌,值为1-m,问能否交换牌,使得第一个人手上的牌奇数个数和偶数个数相同且没有重复的牌

#

既然有重复出现的牌,首先进行去重,之后对于偶数的个数进行分类讨论.

#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
vector<ll>V;
map<ll,ll>vis,cnt,a;
int main() {
    int n,m,i,j,p;
    scanf("%d%d",&n,&m);
    for(i=1; i<=n; i++) {
        scanf("%d",&a[i]);
        if(vis[a[i]] || cnt[a[i]&1]==n/2) V.push_back(i);
        else {
            vis[a[i]]=1;
            cnt[a[i]&1]++;
        }
    }
    p=0;
    for(i=1; i<=m; i++) {
        if(p==V.size()) break;
        if(vis[i]) {
            continue;
        }
        if(cnt[i&1]<n/2) {
            cnt[i&1]++;
            a[V[p++]]=i;
        }
    }
    if(p<V.size()) printf("-1");
    else {
        printf("%d\n",p);
        for(i=1; i<=n; i++) printf("%d ",a[i]);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值