字节跳动2018秋招算法岗第二批

试题链接

							A用户喜好

在这里插入图片描述
在这里插入图片描述
题意:
如图。
思路:
用map把k离散化,开个vector v[N] 把离散化后的k分类存储起来,然后对于每一次询问,在把k离散化后的v[k’]中二分查询。
代码:

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+15;
typedef long long ll;
vector<int>v[N];
map<int,int>mp;
int main()
{
    ll n,cnt=10,m,l,r,x;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>x;
        if(mp[x]<1 )
            mp[x]=++cnt;
        int op=mp[x];
        v[op].push_back(i);
    }
    cin>>m;
    for(int i=1;i<=m;i++)
    {
        cin>>l>>r>>x;
        x=mp[x];
        int l1=lower_bound(v[x].begin(),v[x].end(),l)-v[x].begin();
        int r1=lower_bound(v[x].begin(),v[x].end(),r)-v[x].begin();
        if(l1==v[x].size() || v[x][l1]>r )
        {
            cout<<"0"<<endl;    continue;
        }
        if(v[x][r1]==r)
            r1++;
        cout<<(r1-l1)<<endl;
    }
    return 0;
}

							B手串

在这里插入图片描述
在这里插入图片描述
题意:
如图。
思路:
把颜色分类处理,开前缀和,变环为链。

#include<bits/stdc++.h>
using namespace std;
const int N=2e4+50;
typedef long long ll;
ll vis[55][N];
ll s[55][N];
int main()
{
    int n,m,c,ans=0,len,x;
    cin>>n>>m>>c;
    for(int i=1;i<=n;i++)
    {
        cin>>len;
        for(int j=1;j<=len;j++)
        {
            cin>>x;
            vis[x][i]=1;
        }
    }
    //cout<<"!!!!!!!"<<endl;
    //cout<<vis[];
    for(int k=1;k<=c;k++)
    {
        for(int i=n+1;i<=n+m;i++)
        {
            vis[k][i]=vis[k][i-n];
        }
        for(int i=1;i<=n+m;i++)
        {
            s[k][i]=s[k][i-1]+vis[k][i];
            int l=max(0,i-m);
            if(s[k][i]-s[k][l]>1)
            {
               // cout<<k<<endl;
                ans++;  break;
            }
        }
    }
    cout<<ans<<endl;
    //cout<<"?"<<endl;
    //cout<<vis[49][1]<<" "<<vis[49][2]<<endl;
    return 0;
}

							C字母交换

在这里插入图片描述
在这里插入图片描述

题意:
如图。
思路:分类处理,枚举,尺取。
代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+15;
typedef long long ll;
char str[N];
vector<int>v[30];
int n,m;    int a[N];
int Search(int x,int k,int ln)
{
    int l=k-1,r=k+1,cnt=0,ans=1,op1,op2,op,lf,rf;
    lf=v[x][k],rf=v[x][k];
    while(1)
    {
        op1=1123456;    op2=1123456;
        if(l>=0)
            op1=lf-v[x][l]-1;
        if(r<=ln-1)
            op2=v[x][r]-rf-1;
      //  cout<<l<<" "<<r<<" "<<op1<<" "<<op2<<endl;
        if(op1<=op2)
        {
            if(op1+cnt>m)
                return ans;
            ans++;  cnt+=op1;   l--;    lf--;
        }
        else
        {
            if(op2+cnt>m)
                return ans;
            ans++;  cnt+=op2;   r++;    rf++;
        }
    }
}
int main()
{
    int x,maxn=0;
    scanf("%s",str+1);
    n=strlen(str+1);
    cin>>m;
    for(int i=1;i<=n;i++)
    {
        x=int(str[i]-'a')+1;
        v[x].push_back(i);
    }
//    cout<<v[2][0]<<" "<<v[2][1]<<endl;
    for(int x=1;x<=26;x++)
    {
        int ln=v[x].size();
        if(ln<=1)
        {
            maxn=max(maxn,ln);   continue;
        }
        for(int i=0;i<=ln-1;i++)
        {
            maxn=max(maxn,Search(x,i,ln) );
        }
        //cout<<x<<" "<<maxn<<endl;
    }
    cout<<maxn<<endl;
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值