5.18-5.20 VJ training


A题 
一开始想用暴力循环,但是发现,我找的思路不对。。。然后就在纸上写了2,4,6的结果,发现好像是个递推,然后就试了试(因为8的时候没手算出来,所以死马当活马医),用递推打了个表,然后直接输出对应的元素就行。
#include<bits/stdc++.h>
using namespace std;
int a[31];
int main()
{
    int i;
    a[1] = 2;
    for(i = 2;i<=15;i++)
    {
        a[i] = 2*a[i-1]+2;
    }
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        cout<<a[n/2]<<endl;
    }
}
B题
这个题说实话,,,没有思路,然后问了问大哥,给了点提示之后,发现自己太过于纠结样例了,导致看不懂,这个题的话首先要判断数组的元素种类是否超过他给的周期,如果超过,直接输出-1;如果没超过就去重然后输出,如果不够一个周期然后补1,最后要注意输出的时候直接按照最大周期输出就行。
#include<bits/stdc++.h>
using namespace std;
int main()
{
    set<int > s;
    int n;
    cin>>n;
    while(n--)
    {
        s.clear();
        int l,p;
        set<int >::iterator it;
        cin>>l>>p;
        int t;
        int i;
        for(i = 0;i<l;i++)
        {
            cin>>t;
            s.insert(t);
        }
        if(s.size()>p)
            cout<<-1<<endl;
        else if(s.size()==p)
        {cout<<p*l<<endl;
            for(int j = 0;j < l;j++){
            for(it = s.begin();it!=s.end();it++)
            {
                cout<<*it<<" ";
            }
            }
            cout<<endl;
        }
        else if(s.size()<p)
        {
            cout<<p*l<<endl;
            for(int j = 0;j<l;j++){
            for(it = s.begin();it!=s.end();it++)
            {
                cout<<*it<<" ";
            }
            for(int i = 0;i<(p-s.size());i++)
                cout<<"1 ";
            }
            cout<<endl;
        }
    }
}
C题
直接暴力模拟,关键点是因为a,b的大小不一定,导致同样的方法价格可能不同,所以要比较两种走路的方法花费的大小,然后取最小就行了。
ps:两种方法分别是:
(1)先将两个坐标中小的用方法一减到零,然后用方法二将另一个坐标变成0;
(2)先将两个坐标中小的用方法一变成另一个坐标,然后用方法二将两个坐标同时变为0。
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        long long x,y,a,b;
        cin>>x>>y>>a>>b;
        long long sum,sum2;
        sum = b*min(x,y)+abs(x-y)*a;
        sum2 = a*x+a*y;
        cout<<min(sum,sum2)<<endl;
    }
}
D题
如果字符串中有0、1两种元素,那就直接输出2倍原数组长度的“01”;如果只有一种元素,直接原地输出。
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
using namespace std;
int main()
{
    char s[10000];
    int t;
    cin>>t;
    while(t--)
    {
        scanf("%s",&s);
        int len = strlen(s);
        int i;
        int flag=1;
        for(i = 0;i < len-1;i++)
        {
            if(s[i]!=s[i+1])
            {
                flag = 0;
                break;
            }
        }
        if(flag==1)
            cout<<s<<endl;
        else

        {
            for(i = 0;i < len;i++)
                {
                    cout<<"10";
                    if(i==len-1)
                        cout<<endl;
                }
        }
    }
}
E题
就是判断两个区间是否有交集,上网百度了一下判断两个集合是否有交集的方法,get到了新思路
#include<iostream>
using namespace std;
int main()
{
    int n,t;
    cin>>t;
    while(t--)
    {
        cin>>n;
        int a,b,c,d;
        cin>>a>>b>>c>>d;
        int sa,ea,sb,eb;
        sa = n*(a-b);
        ea = n*(a+b);
        sb = c-d;
        eb = c+d;
        if(max(sa,sb)<=min(ea,eb))
            cout<<"Yes"<<endl;
        else cout<<"No"<<endl;

    }
}

F题
一开始想用滑动窗口,但是发现他的长度不确定,循环感觉会tle,求助了一下大佬,学了一下前缀和,然后,啊真香,就是注意边界,绕乱了好几次,awsl
#include<bits/stdc++.h>
using namespace std;
int a[200001] ;
int c[200001];
int main()
{
    int t;cin>>t;
    while(t--)
    {
        int cnt = 0;
        int k,n;
        cin>>n>>k;
        int i;
        for(i = 1;i<=n;i++)
        cin>>a[i];
        for(int i = 1;i<=n;i++)
        {
            if(a[i-1]<a[i]&&a[i]>a[i+1])
            {
                cnt++;
            }
            c[i] = cnt;
        }
        int maxm = 0,p = 1;
        for(i = 1;i<=n-k+1;i++)
        {
            if(maxm<c[i+k-2]-c[i])
            {
                maxm = c[i+k-2]-c[i];
                p = i;
            }
        }
        cout<<maxm+1<<" "<<p<<endl;
    }
}

 
全部评论

相关推荐

投递美团等公司10个岗位
点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务