牛客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 */
来源:牛客网
题目描述
某天,一只可爱的小兔砸在路上蹦蹦跳跳地走着,怪人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;
}
救救企鹅
链接: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 */
#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 */
来源:牛客网
题目描述
可能很多人要吐槽为什么标题不是“救救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 */