牛客OI周赛7-普及组

比赛页面

表示差点就要被打爆了。(虽然对许多大佬来说水到爆炸)

 

救救喵咪

链接:https://ac.nowcoder.com/acm/contest/372/A
来源:牛客网

题目描述

某天,一只可爱的肥橘喵在路上走,突然遇到了一个怪人,那怪人自称PM6,“小肥喵,这里有一道水题,答对了我就请你吃狗肉,答错了你就请我吃猫肉!”

喵咪瑟瑟发抖:“QAQ什么题?”

PM6道:“给你坐标轴上的N个点,求出对于每个点,有多少个点的 X 坐标和 Y 坐标都大于它。”

毫不意外,蠢肥喵完全不会这道题并面临着被做成猫肉火锅的危险,求求你救救喵咪!

输入描述:

输入包括两行,第一行是正整数n,表示点数,接下来N行每行两个数表示第i个点的横坐标和纵坐标,坐标值都是整数,输入数据中存在坐标相同的点。
对于50%的数据:0<=点的坐标大小<=10000,0<=N<=100
对于100%的数据:0<=点的坐标大小<=10000,0<=N<=1000

输出描述:

输出包括N行,第i行表示有多少个点在点i的右上方。

输入

3
1 2
2 3
4 4

输出

2
1
0

sol:n2暴力随便水。
#include <bits/stdc++.h>
using namespace std;
typedef int ll;
inline ll read()
{
    ll s=0;
    bool f=0;
    char ch=' ';
    while(!isdigit(ch))
    {
        f|=(ch=='-'); ch=getchar();
    }
    while(isdigit(ch))
    {
        s=(s<<3)+(s<<1)+(ch^48); ch=getchar();
    }
    return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
    if(x<0)
    {
        putchar('-'); x=-x;
    }
    if(x<10)
    {
        putchar(x+'0');    return;
    }
    write(x/10);
    putchar((x%10)+'0');
    return;
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('\n')
const int N=1005;
int n;
struct Point
{
    int x,y;
}P[N];
int main()
{
    int i,j;
    R(n);
    for(i=1;i<=n;i++)
    {
        R(P[i].x);
        R(P[i].y);
    }
    for(i=1;i<=n;i++)
    {
        int SS=0;
        for(j=1;j<=n;j++) if(P[j].x>P[i].x&&P[j].y>P[i].y)
        {
            SS++;
        }
        Wl(SS);
    }
    return 0;
}
/*
input
3
1 2
2 3
4 4
output
2
1
0
*/
View Code

 

 

救救兔子
 链接:https://ac.nowcoder.com/acm/contest/372/B
来源:牛客网

题目描述

某天,一只可爱的小兔砸在路上蹦蹦跳跳地走着,怪人PM6出现了,于是小兔子被盯上了。

PM6:“免子。哦不,小兔子。你长得真好…不对,真可爱。我这里有一道很容易很容易的题目,答对了我就请你吃萝卜,答错了你就请我吃兔肉,好不好呀~~?”

小兔砸:“萝卜!?好呀好呀好呀。”于是笨笨的兔纸入套了。

PM6:“我这里有一个由 N 个数组成的序列,给你 M 个询问,每个询问会给你一个数 X ,对于每个询问,你要回答出序列中与这个值最接近的元素。”

听完题后,兔子吓成一坨免子了,面临着变成红烧兔头的危险,求求你救救兔子!

输入描述:

第一行包含一个整数N,为序列长度。
第二行包含N个整数,为序列各元素。
第三行包含一个整数M,为PM6的询问个数。
接下来M行,每行一个整数X,为要询问最接近元素的给定值。
对于40%的数据:1<=N<=10000,1<=M<=1000
对于另外10%的数据:M=1
对于100%的数据:1 <=N<= 100000,1<=M<=10000,0<=序列中的每个数,X<=1e9

输出描述:

M行,每行有一个整数,为最接近相应给定值的元素值,保持输入顺序。若有多个值满足条件,输出最小的一个。

输入

5
2 4 5 5 7
3
2
5
6

输出

2
5
5

sol:先把读入的数排个序,对于每个询问二分第一个大于等于它的位置p,判一下p-1和p即可,注意边界
#include <bits/stdc++.h>
using namespace std;
typedef int ll;
inline ll read()
{
    ll s=0;
    bool f=0;
    char ch=' ';
    while(!isdigit(ch))
    {
        f|=(ch=='-'); ch=getchar();
    }
    while(isdigit(ch))
    {
        s=(s<<3)+(s<<1)+(ch^48); ch=getchar();
    }
    return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
    if(x<0)
    {
        putchar('-'); x=-x;
    }
    if(x<10)
    {
        putchar(x+'0');    return;
    }
    write(x/10);
    putchar((x%10)+'0');
    return;
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('\n')
const int N=100005;
int n,a[N];
int Q;
int main()
{
    int i;
    R(n);
    for(i=1;i<=n;i++) R(a[i]);
    sort(a+1,a+n+1);
    n=unique(a+1,a+n+1)-a-1;
    R(Q);
    while(Q--)
    {
        int x=read();
        int Pos=lower_bound(a+1,a+n+1,x)-a;
        if(Pos==1) Wl(a[Pos]);
        else if(Pos==n+1) Wl(a[Pos-1]);
        else
        {
            if(a[Pos]-x<x-a[Pos-1]) Wl(a[Pos]);
            else Wl(a[Pos-1]);
        }
    }
    return 0;
}
View Code

 

 

救救企鹅

链接:https://ac.nowcoder.com/acm/contest/372/C
来源:牛客网

题目描述

另一天,一只可爱的围着围巾的肥企鹅在路上摇摇晃晃地走着,遇上了迎面走来的打着饱嗝的PM6。小企鹅预感不妙,这不就是最近有名的恶人PM6么!吓得立刻扭头就想跑。

PM6:“小火汁,站住!我不吃你(谁叫你是保护动物)。我这有一道简单题,如果你答对了,我就给你吃鱼肉,如果你答错了,就免费帮我充游戏币!”

企鹅:“_(:3J∠)_(默默摘掉围巾)”

PM6:“我给你一个文本串 S ,再给你两个串A、B,你要将文本串中的 A 都转换成 B ,转换后的字符不再参与转换,输出最终的文本串。”

求求你救救企鹅!

输入描述:

第一行输入一个文本串 S 。
第二行输入字符串 A 。
第三行输入字符串 B 。
|S|为S的长度,|A|为A的长度,|B|为B的长度,所有字符都是小写字母,保证 |A| <= |S| 。
对于50%的数据:1<= |A|、|B|、|S| <=1000
对于100%的数据:1<= |A|、|B|、|S| <=1000000

输出描述:

只有一行,输出转换后的文本串。

输入

abababcd 
ab
cd

输出

cdcdcdcd


sol:一开始想到Hash,然后用栈O(n)扫一遍,一直WA(是Hash被卡??),然后气死了写了Kmp
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read()
{
    ll s=0;
    bool f=0;
    char ch=' ';
    while(!isdigit(ch))
    {
        f|=(ch=='-'); ch=getchar();
    }
    while(isdigit(ch))
    {
        s=(s<<3)+(s<<1)+(ch^48); ch=getchar();
    }
    return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
    if(x<0)
    {
        putchar('-'); x=-x;
    }
    if(x<10)
    {
        putchar(x+'0'); return;
    }
    write(x/10);
    putchar((x%10)+'0');
    return;
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('\n')
const int W=97;
const int N=1000005;
char S[N],A[N],B[N],Ans[N];
int Top=0,Last=0;
int LS,LA,LB;
ll Hash[N],Pow[N],HA=0;
int main()
{
    int i,j;
    scanf("%s",S+1); LS=strlen(S+1);
    scanf("%s",A+1); LA=strlen(A+1);
    Pow[0]=1;
    for(i=1;i<=LA;i++)
    {
        HA=HA*W+(A[i]-'a'+1);
    }
    scanf("%s",B+1); LB=strlen(B+1);
    Hash[0]=0;
    for(i=1;i<=LS;i++)
    {
        Ans[++Top]=S[i];
        Hash[i]=Hash[i-1]*W+(Ans[i]-'a'+1);
        Pow[i]=Pow[i-1]*W;
        if(Top-Last>=LA)
        {
            if(Hash[i]-Hash[i-LA]==HA*Pow[i-LA])
            {
                for(j=1;j<=LA;j++) Top--;
                for(j=1;j<=LB;j++) Ans[++Top]=B[j];
                Last=i;
            }
        }
    }
    for(i=1;i<=LS;i++)
    {
        putchar(Ans[i]);
    }
    return 0;
}
/*
input
abababcd
ab
cd
output
cdcdcdcd
*/
Hash Wa

#include <bits/stdc++.h>
using namespace std;
typedef int ll;
inline ll read()
{
    ll s=0;
    bool f=0;
    char ch=' ';
    while(!isdigit(ch))
    {
        f|=(ch=='-'); ch=getchar();
    }
    while(isdigit(ch))
    {
        s=(s<<3)+(s<<1)+(ch^48); ch=getchar();
    }
    return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
    if(x<0)
    {
        putchar('-'); x=-x;
    }
    if(x<10)
    {
        putchar(x+'0'); return;
    }
    write(x/10);
    putchar((x%10)+'0');
    return;
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('\n')
const int N=1000005;
char S[N],A[N],B[N];
/*
    ABABABAB
    Next[1]=0
    Next[2]=0
    Next[3]=1
*/
int Kmp_Next[N];
inline void Pre_Next(char *S)
{
    int i,j=0,n=strlen(S+1);
    Kmp_Next[0]=Kmp_Next[1]=0;
    for(i=2;i<=n;i++)
    {
        while(j&&(S[i]!=S[j+1])) j=Kmp_Next[j];
        if(S[i]==S[j+1]) j++;
        Kmp_Next[i]=j;
    }
}
bool Can[N];
inline void Pipei(char *S,char *T)
{
    int i,j=0,n=strlen(S+1),m=strlen(T+1);
    for(i=1;i<=n;i++)
    {
        while(j&&(S[i]!=T[j+1])) j=Kmp_Next[j];
        if(S[i]==T[j+1]) j++;
        if(j==m)
        {
            Can[i-m+1]=1;
        }
    }
}
int main()
{
    int i,n,m;
    scanf("%s",S+1); n=strlen(S+1);
    scanf("%s",A+1); m=strlen(A+1);
    scanf("%s",B+1);
    Pre_Next(A);
    Pipei(S,A);
    for(i=1;i<=n;i++)
    {
        if(Can[i])
        {
            printf("%s",B+1); i=i+m-1;
        }
        else putchar(S[i]);
    }
    return 0;
}
/*
input
abababcd 
ab
cd
output
cdcdcdcd
*/
Kmp AC

 


数糖纸

 链接:https://ac.nowcoder.com/acm/contest/372/D
来源:牛客网

题目描述

可能很多人要吐槽为什么标题不是“救救blabla”了。

怪人PM6喜欢数糖纸,不同的糖纸有不同的颜色,一共有 N 张糖纸,第 i 张糖纸颜色为 Ci ,它们的位置都是固定的。PM6喜欢五彩缤纷的糖纸,所以他不希望有重复的颜色。他有一次机会,可以收集任意一段连续区间内的糖纸。求出PM6最多能收集多少张糖纸。

输入描述:

第一行一个正整数 N ,表示共有 N 张糖纸。
第二行共有 N 个正整数,第 i 个正整数表示第 i 张糖纸的颜色 Ci
对于20%的数据:1<=N<=100
对于40%的数据:1<=N<=1000
对于100%的数据:1<=N<=1e6,0<=Ci<=1e9

输出描述:

一个整数表示PM6最多能收集多少张糖纸。

输入

5
1 2 2 3 4

输出

3

说明

PM6可以收集第3到第5张的糖纸,共有三张。

sol:这样的题放T4就是毒瘤,很容易发现是O(n)扫一遍,用一个队列存,如果前面有当前这个颜色就弹队首,队尾一个个加进来
但是颜色的范围是1e9,还卡Hash。。我写Map TLE,写Hash,换了好几个模数qaq
#include <bits/stdc++.h>
using namespace std;
typedef int ll;
inline ll read()
{
    ll s=0;
    bool f=0;
    char ch=' ';
    while(!isdigit(ch))
    {
        f|=(ch=='-'); ch=getchar();
    }
    while(isdigit(ch))
    {
        s=(s<<3)+(s<<1)+(ch^48); ch=getchar();
    }
    return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
    if(x<0)
    {
        putchar('-'); x=-x;
    }
    if(x<10)
    {
        putchar(x+'0'); return;
    }
    write(x/10);
    putchar((x%10)+'0');
    return;
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('\n')
const int N=1000005;
const int Mod=1651469;
int n,Cor[N],Que[N];
int Hash[Mod+5];
int main()
{
    int i,Head=0,Tail=0,ans=0;
    R(n);
    for(i=1;i<=n;i++) R(Cor[i]);
    for(i=1;i<=n;i++)
    {
        while(Head<Tail&&Hash[Que[Tail]]>1)
        {
            Hash[Que[Head++]]--;
        }
        ans=max(ans,Tail-Head+1);
        Que[++Tail]=Cor[i]%Mod;
        Hash[Que[Tail]]++;
    }
    Wl(ans);
    return 0;
}
/*
input
5
1 2 2 3 4
output
3
*/
View Code

 

 
posted @ 2019-03-06 22:36  yccdu  阅读(365)  评论(0编辑  收藏  举报