czl蒻蒟的OI之路13

  • XJOI奋斗群蒻蒟群群赛10 RANK排名6
      • T1Compote 已AC
          • 题意
          • 分析过程
          • 给出题解
      • T2Decoding已AC
          • 题意
          • 分析过程
          • 给出题解
      • T3Tram已AC
          • 题意
          • 分析过程
          • 给出题解
      • T4Green and Black TeaWA三次之后AC
          • 题意
          • 分析过程
          • 给出题解
      • T5Numbers Exchange 已AC
          • 题意
          • 分析过程
          • 给出题解
      • T6Music in Car
          • 题意
          • 分析过程
          • 给出题解
      • T7New Roads
          • 题意
          • 分析过程
          • 给出题解
      • 蒻蒟的一周总结

—>XJOI奋斗群(蒻蒟群)群赛10<— RANK排名6

T1:Compote (已AC)

题意:

给你三个数,问你有没有另外3个数,他们的大小之比分别为1:2:4,并且每一个数都对应的小于给出的三个数。

分析过程:

这题应该不用多说了吧,直接暴力从大到小枚举就行了。

给出题解:
#include
using namespace std;

int main()
{
    int a,b,c;
    int res;
    bool flag=false;
    scanf("%d %d %d",&a,&b,&c);
    for(int i=a;i>=1;i--)
    {
        if(i*2<=b&&i*4<=c)
        {
            res=i;
            flag=true;
            break;
        }
    }
    if(flag==true)printf("%d",res*7);
    else printf("0");
    return 0;
}

T2:Decoding(已AC)

题意:

给你一个长度为n的字符串,如果n为偶数,那么把第一个字母放中间,之后的字母一个放它右边,一个放它左边,如果n为奇数,那么把第一个字母放中间,之后的字母一个放它左边,一个放它右边,输出这个字符串。

分析过程:

还是一样,直接按照题意进行模拟就行了。

给出题解:
#include
using namespace std;

int main()
{
    int a,b,c;
    int res;
    bool flag=false;
    scanf("%d %d %d",&a,&b,&c);
    for(int i=a;i>=1;i--)
    {
        if(i*2<=b&&i*4<=c)
        {
            res=i;
            flag=true;
            break;
        }
    }
    if(flag==true)printf("%d",res*7);
    else printf("0");
    return 0;
}

T3:Tram(已AC)

题意:

有一条路,可以把它看成一个数轴,从0~s,一个人要从x1到达x2,每t1秒走1米。还有一辆公车,刚开始在d点,前进方向为向左或向右,每t2秒走1米,到达边缘时会立刻掉头,问这个人到达x2点的最短时间。(这个人只能在整数点上下车)

分析过程:

因为这个人上下车是没有时间的,所以我们可以把人和车分开来考虑,只要车经过了这个人,就可以认为这个人上车了,所以把人和车到达x2的时间分开来进行计算,就可以知道最短的时间了。

给出题解:
#include
using namespace std;

int main()
{
    int s,x1,x2;
    int t1,t2;
    int d,f;
    bool can;
    scanf("%d %d %d",&s,&x1,&x2);
    scanf("%d %d",&t1,&t2);
    scanf("%d %d",&d,&f);
    int cnt1,cnt2;
    cnt1=abs(x1-x2)*t2;
    if(f==1&&d>=x2&&x1>=x2)
    {
        cnt2=(s-d)+(s-x2);
        cnt2=cnt2*t1;
    }
    else if(f==1&&d>=x2&&x1<=x2)
    {
        cnt2=s+(s-d)+x2;
        cnt2=cnt2*t1;
    }
    else if(f==1&&d=d&&x1<=x2)
    {
        cnt2=(x2-d)*t1;
    }
    else if(f==1&&d=x2)
    {
        cnt2=(s-d)+(s-x2);
        cnt2=cnt2*t1;
    }
    else if(f==1&&ds-d)+s+x2;
        cnt2=cnt2*t1;
    }
    else if(f==-1&&d>=x2&&x1>=x2&&x1<=d)
    {
        cnt2=(d-x2)*t1;
    }
    else if(f==-1&&d>=x2&&x1<=x2)
    {
        cnt2=x2+d;
        cnt2=cnt2*t1;
    }
    else if(f==-1&&d>=x2&&x1>d)
    {
        cnt2=d+s+(s-x2);
        cnt2=cnt2*t1;
    }
    else if(f==-1&&d*t1;
    }
    else if(f==-1&&dx2)
    {
        cnt2=d+s+(s-x2);
        cnt2=cnt2*t1;
    }
    int res;
//  cout<" "<printf("%d",res);
}

T4:Green and Black Tea(WA三次之后AC)

题意:

有绿茶和黑茶两种茶,一个人要喝完这些茶,问能不能拍出一种顺序,让连续喝的相同品种的茶不超过k个,不行就输出-1。

分析过程:

可以先把多的一种茶都摆出来,然后判断要把它分成几段,并且每段的长度都不超过k的最少的另一种茶的数量ans。判断ans和较少的茶的数量是否相同就可以了。然后就可以先把较少的茶放进print数组中,剩余的都放另一种茶就行了。

给出题解:
#include
using namespace std;

char print[100005];
int main()
{
//  freopen("out.txt","w",stdout);
    int n,k,b,g;
    scanf("%d %d %d %d",&n,&k,&g,&b);
    int cnt1=min(b,g);
    int cnt2=max(b,g);
    int ans;
//  cout<" "<if(cnt2%k==0)ans=cnt2/k-1;
    else ans=cnt2/k;
    memset(print,'0',sizeof(print));
//  cout<int a=1;
    if(ans>cnt1)printf("NO");
    else if(ans<=cnt1&&cnt1!=cnt2)
    {
        if(g<=k&&b<=k)
        {
            for(int i=1; i<=g; i++)
            {
                printf("G");
            }
            for(int i=1; i<=b; i++)
            {
                printf("B");
            }
        }
        else
        {
            int x=g,y=b;
            if(cnt1==g)
            {
                while(g>0)
                {
                    for(int i=k+a; i<=n; i+=k+1)
                    {
                        print[i]='G';
                        g--;
                        if(g==0)break;
                    }
                    a++;
                }
            }
            else 
            {
                while(b>0)
                {
                    for(int i=k+a; i<=n; i+=k+1)
                    {
                        print[i]='B';
                        b--;
                        if(b==0)break;
                    }
                    a++;
                }
            }
            for(int i=1; i<=n; i++)
            {
                if(cnt1==y)
                {
                    if(print[i]=='0')print[i]='G';
                }
                else
                {
                    if(print[i]=='0')print[i]='B';
                }
                printf("%c",print[i]);
            }
        }
    }
    else if(ans<=cnt1&&cnt1==cnt2)
    {
        for(int i=1;i<=n/2;i++)
        {
            printf("GB");
        }
    }
    return 0;
}

T5:Numbers Exchange (已AC)

题意:

有一个人有n张牌,另一个人有1-m共m张牌,问能不能通过牌的呼唤,让第一个人手中牌的奇数和偶数数量相同,并且都不重复。可以就输出最少交换次数,并输出交换后的牌。

分析过程:

首先考虑去重的工作; 在去重之前;先算出; 原来的n张卡片里面,卡片上的数字是奇数的数字个数odd; 然后两个变量nexto和nexte分别表示下一个没被交换的奇数和偶数(1..m里面); 对于重复出现的卡片; 看看odd和n/2的关系;
如果 odd>n/2
则不能再来奇数了,所以只能拿一张偶数的和它交换(不管重复的这张的奇偶性);
(只是如果是奇数的,则奇数张数递减);
如果 odd==n/2
则拿一张和这个数字奇偶性相同的卡片来交换;
如果 odd< n/2
则不能来偶数了,需要拿一张奇数的卡片和它交换(仍旧不管重复的这张的奇偶性如何,都是拿一张奇数的)
这张重复的是偶数的话,odd++;
去重结束之后;
再根据odd和n/2的关系大小贪心换每一个数字;
如果 odd< n/2
且遇到了一个偶数;
则拿一个奇数来和它换,odd++
如果 odd>n/2
且遇到了一个奇数
则拿一个偶数和它换,odd–

给出题解:
#include 
using namespace std;
#define LL long long 


const int N = 2e5+5;
int n,m,a[N],odd=0,nod,neven,flag,ans=0;
map <int,int> d;

void change_even(int i)
{
    while (neven<=m && d[neven])
        neven+=2;
    if (neven>m)
        flag = 0;
    else
        d[a[i]]--,d[neven]=1,a[i] = neven,neven+=2;
}

void change_odd(int i)
{
    while (nod<=m && d[nod])
        nod+=2;
    if (nod>m)
        flag = 0;
    else
        d[a[i]]--,d[nod]=1,a[i] = nod,nod+=2;
}

int main()
{
    cin >> n >> m;
    for(int i=1;i<=n;i++)
    {
        cin >> a[i];
        d[a[i]]++;
        if (a[i]%2==1) odd++;
    }
    nod = 1,neven = 2;
    flag = 1;

    for(int i=1;i<=n;i++)
    {
        if (d[a[i]]==1) continue;
        ans++;
        if (odd>n/2)
        {
            if (a[i]%2==1)
                odd--;
            change_even(i);
        }
        else if (odd==n/2)
        {
            if (a[i]%2==0)
                change_even(i);
            else
                change_odd(i);
        }
        else
        {
            if (a[i]%2==0)
                odd++;
            change_odd(i);
        }
    }
    for(int i=1;i<=n;i++)
    {
        if (odd==n/2) break;
        if (odd2)
        {
            if (a[i]%2==0)
            {
                odd++;
                ans++;
                change_odd(i);
            }
        }
        else
        {
            if (a[i]%2==1)
            {
                odd--;
                ans++;
                change_even(i);
            }
        }
    }
    if (odd!=n/2 || !flag)
        return cout<<-1<0;
    cout << ans << endl;
    for(int i=1;i<=n-1;i++)
    cout << a[i] <<" ";
    cout << a[n]<return 0;
}

T6:Music in Car

题意:
分析过程:
给出题解:

T7:New Roads

题意:
分析过程:
给出题解:

蒻蒟的一周总结:

这周感觉自己确实进步了很多,先是在上周末打了一次codeforces的比赛,虽然只A了两道题,但确实也是因为自己的技术有限。这周在打比赛的时候,可以发现自己AB题的速度越来越快了。但是做到后面几题的时候,虽然有了想法,但在最后都很难能够在自己的代码上体现出来,最后在赛和同学交流的时候才会茅塞顿开,才能够自己写出代码。希望以后再比赛的时候就能够自己想出想法,并且把它打出来,不管错或对,都是要在后面修改的。还有一点就是自己在打代码之前,有时思考的会比较少,导致打代码的时候经常进行大幅度的修改,修改到后面连自己都有点不知道什么意思了。所以以后可以在相应的函数后面加上一些注释,来帮助自己理解。离NOIP初赛还有半个月左右的时间,这是我第一次比赛,心里很没底,所以就让接下来的训练让自己变得更加有底一些吧。

你可能感兴趣的:(蒟蒻OI之路)