奋斗群群赛---13,14 跑跑更健康!

奋斗群群群赛—13,14

群赛13

T1:Dima and Guards

题目位置:

T1位置所在

题意:

就是有四个守卫,你需要贿赂一行的守卫,每行有2个守卫,有4个数据,分别是守卫1的蛋糕和茶水的值和守卫2的,,,如果输入的数据的钱数能够贿赂,就是出方案的花费!

AC代码:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n,flag=0,loc=0,x,y,min1;
    scanf("%d",&n);
    for(int i=1; i<=4; i++)
    {
        int a,b,c,d;
        scanf("%d%d%d%d",&a,&b,&c,&d);
        x=min(a,b);
        y=min(c,d);
        if(x+y<=n&&flag==0)
        {
            min1=x;
            loc=i;
            flag=1;
        }
    }
    if(flag==1)
    {
        printf("%d %d %d\n",loc,min1,n-min1);

    }
    else
        printf("-1\n");
    return 0;
}

小反思:

无…

T2:Dima and To-do List

题目位置:

T2位置所在

题意:

就是每次取物品隔着m个数来取,求输出的最大的和值的情况的初始的点的位置.

AC代码:

#include <bits/stdc++.h>
using namespace std;
const int N=100005;
int a[N];
long long t[N];
int main()
{
    int n,m,tot,loc;
    int max=999999999;
    scanf("%d%d",&n,&m);

    for(int i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
    }
    for(int i=1; i<=m; i++)
    {
        int ans=0;
        for(int j=i; j<=n; j+=m)
            {
            ans+=a[j];
            }
        if(ans<max)
        {
            max=ans;
            loc=i;
        }
    }

    printf("%d\n",loc);
    return 0;
}

T3:Dima and Salad

题目位置:

T3位置所在

题意:

有n个蛋糕,输入了第一行是各个蛋糕的美味值ai,接下来是花费值bi,求使得能让取了m个蛋糕的美味值的总和除以m个蛋糕的花费之总和为k!
求最大的美味值总和,并且输出∑ai的知就好了!

想法:

就是将a[i]的值每次都减去k*b[i],就相当于是分离正系数的一个做法,就像这样:

        for(int i=1; i<=n; i++)
    {
        x[i]=a[i]-k*b[i]; // +  ´óÁË!  // - С ÁË!
    }

在就会得到一些有正有负的x[i]数组,只要选取将其和为0 的数据就是可以了!因为这时候就是可以整除,因为互补嘛!

AC代码:

#include <bits/stdc++.h>
using namespace std;
const int N=10005;
int a[N],b[N],x[N];
int dp[105][N];
int main()
{
    int n,k;
    scanf("%d%d",&n,&k);
    int V=n*100;
    for(int i=1; i<=n; i++)
        scanf("%d",&a[i]);
    for(int i=1; i<=n; i++)
        scanf("%d",&b[i]);

    memset(dp,192,sizeof(dp));
    dp[0][V]=0;
    //x Ëù´æ´¢µÄÖµ¾ÍÊÇÒ»¸öËùνµÄÀíÏ뻯ֵ , ¶øÕý¸º±íʾÁËÆä ´óСÓë·ñ!
    for(int i=1; i<=n; i++)
    {
        x[i]=a[i]-k*b[i]; // +  ´óÁË!  // - С ÁË!
    }

    for(int i=1; i<=n; i++)
    {
        for(int j=2*V; j>=0; j--)
            dp[i][j]=max(dp[i-1][j],dp[i-1][j-x[i]]+a[i]);
    }
    printf("%d\n",dp[n][V]?dp[n][V]:-1);
    return 0;
}

T4:

题目位置:

T4位置所在

题意:

有n个点m条无向边。初始你需要选择一个整数x,走第i条边的限制为Li <= x <= Ri,假设1-n的一条路径上可以选择的整数x有ans,问你最大的ans。
(所以说就是并查集,加上一个暴力枚举就好了!)

AC代码

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=2003;
int fa[N],ans;
struct tree
{
    int end,start,l,r;
} t[3005];
bool com(tree x,tree y)
{
    return x.l<y.l?true:false;
}
int find(int x)
{
    return fa[x]==x?x:fa[x]=find(fa[x]);
}
void add(int x,int y)
{
    fa[find(x)]=find(y);
}
bool judge(int x,int y)
{
    if(find(x)==find(y))
        return true;
    else
        return false;
}

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1; i<=m; i++)
    {
        scanf("%d%d%d%d",&t[i].start,&t[i].end,&t[i].l,&t[i].r);
    }
    sort(t+1,t+1+m,com);
    for(int i=1; i<=m; i++)
    {
        //只是当做 t[i].r 为最大的上限就好了! 
        for(int j=1; j<=n; j++)
            fa[j]=j;
        for(int j=1; j<=m; j++)
        {
            if(t[j].l>t[i].r)
                break;
            if(t[j].r<t[i].r)
                continue;
            add(t[j].end,t[j].start);
            if(judge(1,n))
            {
                ans=max(ans,t[i].r-t[j].l+1);
                break;
            }
        }
    }
    ans?printf("%d\n",ans):printf("Nice work, Dima!\n");
    return 0;
}

小反思:

就是相当于一些大大小小的水管一样的,每个数据都有上限和下限,所以就是问你,有多少的水流能够一次性流到底:那么就是变成了想法就是枚举一个数据的下限!就是a[i].r的值,表示我每次只是去比它大的值,别的不去,就是这个思路了!

T5:Dima and Magic Guitar

题目位置:

T5位置所在

题意:

就是求曼哈顿最远距离……

AC代码:

#include <bits/stdc++.h>
using namespace std;
const int N=20005;

int f[N][10];
int main()
{
    int n,m,k,len,x;
    scanf("%d%d%d%d",&n,&m,&k,&len);
    //Ö÷ҪʹµÃ ¼õºÅÇ°µÄ¾¡Á¿µÄ´ó ¼õºÅºóµÄ¾¡Á¿Ð¡!
    for(int i=1;i<=k;i++)
    {
        f[i][1]=f[i][2]=-99999;
        f[i][3]=f[i][4]=99999;
    }
    for(int i=1; i<=n; i++)
        for(int j=1; j<=m; j++)
        {
            scanf("%d",&x);
            f[x][1]=max(f[x][1],i+j);
            f[x][2]=max(f[x][2],i-j);
            f[x][3]=min(f[x][3],i+j);
            f[x][4]=min(f[x][4],i-j);
        }
    int sta,end,ans=0;
    scanf("%d",&sta);
    for(int i=2; i<=len; i++)
    {
        scanf("%d",&end);
        ans=max(f[sta][1]-f[end][3],ans);
        ans=max(f[end][2]-f[sta][4],ans);
        ans=max(f[sta][2]-f[end][4],ans);
        ans=max(f[end][1]-f[sta][3],ans);
        sta=end;
    }
    printf("%d\n",ans);
    return 0;
}

小反思:

one:
(x1-x2)  + (y1-y2)  ---> (x1+y1) - (x2+y2)
two:
-(x1-x2) + (y1-y2)  --->  (x2-y2) - (x1-y1)
three:
 (x1-x2) - (y1-y2)  ---> (x1-y1) - (x2-y2)
four:
-(x1-x2) - (y1-y2)  ---> (x2+y2) - (x1+y1)

群赛14:

T1:Compote

题目位置:

T1位置所在

题意:

不说了,直接上代码!

AC代码

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int a,b,c;
    scanf("%d%d%d",&a,&b,&c);

    a/=1;
    b/=2;
    c/=4;
    int tot=min(min(a,b),c);
    printf("%d\n",tot*7);
    return 0;
}

T2:Decoding

题目位置:

T2位置所在

题意:

输入1个长度为n(1<=n<=2000)的字符串s1是由另一个长度为n的字符串s2变化而来,变化规则是:每次都把s2中间(如果长度是偶数就取小的一个)的字母拿出放到s1的第一个上,由此反复进行直到取完。要求输出s2这个字符串。

AC代码:

找规律!!!

#include<bits/stdc++.h>
using namespace std;
const int N=2005;
char a[N],s[N];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1; i<=n; i++)
    {
    cin>>a[i];
    }
    if(n%2==1)
    {
        int j=n/2+1;
        s[j]=a[1];
        for(int i=1;i<=n/2;i++)
        {
            s[j-i]=a[i*2];
            s[j+i]=a[i*2+1];
        }
        for(int i=1;i<=n;i++)
        cout<<s[i];
    }
    else
    {
        int j=n/2;
        s[j]=a[1];
        for(int i=1;i<=n/2;i++)
        {
            s[j+i]=a[i*2];
            if(j-i>0)
            s[j-i]=a[i*2+1];
        }
        for(int i=1;i<=n;i++)
        cout<<s[i];
    }
}

T3:Tram

题目位置:

T3位置所在

题意:

在一条直线上,坐标从0到S。 人要从X1位置向X2位置移动,前进一个单位要t2时间。 当人在X1位置,车子在p位置,前进一个单位要t1秒。方向为d,d==1表示从正方向前进, d == -1表示负方向前进。 人可以在与车子相遇时,坐上车子。

AC代码:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int s,x1,x2;
    int t1,t2;
    int p,d;
    scanf("%d%d%d%d%d%d%d",&s,&x1,&x2,&t1,&t2,&p,&d);
    int time=abs(x2-x1)*t2; //ͽ²½ÐÐ×ßµÄtime!
//  int car=time/t1; // Æû³µ×î¶à×ßÁ˶àÉÙ!
// int tiss  car
    int tot1,tot2;
    tot1=time;
    if(d==1)
    {
        if(p<=x1&&x1<x2)
            tot2=(x2-p)*t1;
        else if(x2>x1)
            tot2=(2*s+x2-p)*t1;
        else if(x2<x1)
            tot2=(2*s-x2-p)*t1;
    }
    else
    {
        if(p>=x1&&x2<x1)
            tot2=(p-x2)*t1;
        //x1 x2
        else if(x2<x1)
            tot2=(p+2*s-x2)*t1;
        else if(x1<x2)
            tot2=(p+x2)*t1;
    }

    if(tot2>tot1)
        cout<<tot1<<endl;
    else
        cout<<tot2<<endl;

    return 0;
}

小反思:

这道题目的关键就是抓住车到终点的时间和人到达终点的时间的min值!
就是这么妙的题目!

T4:Green and Black Tea

题目位置:

T4位置所在

题意:

就是喝红茶和黑茶,每次不能够连续喝k次,输出喝茶的方案就好!

AC代码:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n,k,a,b;
    scanf("%d%d%d%d",&n,&k,&a,&b);
    // a Â̲è G
    // b ºÚ²è  B
    int maxn=max(a,b);
    int minn=min(a,b);
    if((maxn-1)/k>minn)
    {
        cout<<"NO";
        return 0;
    }
    if(a<=b)
    {
        int cha=b-a;
        while(cha>k-1&&b>=k&&a>0)
        {
            b-=k;
            a--;
            for(int i=1; i<=k; i++)
                cout<<"B";
            cout<<"G";
            cha=b-a;
        }
        for(int i=1; i<=cha; i++)
        {
            cout<<"B";
            b--;
        }
        for(int i=1; i<=a+b; i+=2)
            cout<<"G"<<"B";
    }
    else
    {
        int cha=a-b;
        while(cha>k-1&&a>=k&&b>0)
        {
            a-=k;
            b--;
            for(int i=1; i<=k; i++)
                cout<<"G";
            cout<<"B";
            cha=a-b;
        }
        for(int i=1; i<=cha; i++)
        {
            cout<<"G";
            a--;
        }
        for(int i=1; i<=a+b; i+=2)
            cout<<"B"<<"G";
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值