牛客OI周赛10——提高组

    xiaoxiao2023-10-31  176

    A题——风雨无阻 题目描述 许cosin的宝贝手表被他的仇人gen海偷走了。他决定秘密前往gen海家,去找回他的手表。 许cosin历经千辛万苦,耗时3天,终于找到了gen海家。他通过观察发现gen海不在家,于是他决定偷偷潜入gen海家,然后找回手表。但他在gen海家的门前发现了一个密码锁,他必须解开这个锁才能进入gen海家。可是许cosin实在是太silly了,于是他就向你请教。请快速解决这个问题,gen海还有1秒就会回家了。 锁上有两行,第一行一个数字N。第二行是一串字符串S(|S|≤6105),字符串由许多子串构成,每个子串的格式均是XA 其中X是一个运算符,A是一个数字。X可能是,+,-, % %,表示次方)。 现在需要把数字N代入字符串S,从左到右进行运算。密码就是运算结果的绝对值。

    题目保证运算过程中N在 int int(-2147483648~2147483647)范围内,^后面的数字只能为2。运算过程从左至右,不满足运算的优先级(详见样例) 输入描述: 两行,第一行一个正整数N 第二行是一个字符串S 输出描述: 一个数,表示运算结果的绝对值 示例: 5 -7*3 输出 6

    ps:这题有点坑,明明说了在int范围内的,结果最后有一个样例没过,后来改成long long才过的,后面看了大佬们尖端的代码,感觉自己就是个zz,mmp orz

    #include<bits/stdc++.h> using namespace std; typedef long long ll; char a[600005],b[1000]; int chack(char a){ if(a=='*')return 1; if(a=='+')return 2; if(a=='-')return 3; return 4; } int main(){ ll n,p=0; cin>>n; cin>>a; ll len1=strlen(a); for(ll i=0;i<len1;i++){ if(a[i]<'0'||a[i]>'9'){ if(a[i]=='^'){ n*=n; i++;continue; } else{ ll w=chack(a[i]); ll sum=0,k=0,g; for(ll j=i+1;a[j]>='0'&&a[j]<='9';j++){ b[k++]=a[j]; } g=k; for(ll j=0;j<k;j++){ g--; sum+=(b[j]-'0')*pow(10,g); } if(w==1)n*=sum; if(w==2)n+=sum; if(w==3)n-=sum; if(w==4)n%=sum; i+=k; } } } cout<<abs(n)<<endl; return 0; }

    大佬代码:

    #include<bits/stdc++.h> using namespace std; long long m,n; char c; int main(){ scanf("%lld",&n); while(~scanf(" %c%lld",&c,&m)){ if(c=='+')n+=m; else if(c=='-')n-=m; else if(c=='*')n*=m; else if(c=='%')n%=m; else if(c=='^')n*=n; else break; } if(n<0)n=-n; printf("%lld\n",n); return 0; }

    B题——Taeyeon的困惑 题目描述 今天,YPC正在热舞之中,嘴里唱着BJLY的神曲,沉浸在了自己的世界里。 然而Taeyeon又突然抽了一下,问YPC一个问题: 在一个长度为n的区间中,子区间[1,m],[2,m+1],[3,m+2],…,[n-m+1,n]中每个区间前K小之和的和是多少。

    其中一个区间的前k小之和指的是将这个区间内的所有数从小到大排序后求出最前面的k个数之和 由于YPC热舞的起劲,无法自拔,于是这个问题只能你来回答。 输入描述: 第一行三个整数:n,m,K,意思如题 第二行n个正整数:a[i],意思如题 输出描述: 输出仅一行,每个区间前K大的数之和的和。

    样例1: 输入 6 3 2 2 3 1 4 5 6 输出 21

    说明:链接:https://ac.nowcoder.com/acm/contest/900/B 来源:牛客网

    对于30%数据:1≤n,m≤1000,0≤k≤m≤n,0≤a[i]≤105,m接近于n/2 对于100%数据:1≤n,m≤105,0≤k≤m≤n,0≤a[i]≤105,m接近于n/2。 保证数据纯随机

    ps:我本来想暴力骗点分的,结果一分没得,话说,正解是两个set来维护,反正我不会,弱爆了 符大佬代码:

    #include<cstdio> using namespace std; const int MAXN=100005; typedef long long LL; int n,m,K,Now,Num,a[MAXN],hsh[MAXN];LL Ans,Sum; #include<cctype> int read(){ int ret=0;char ch=getchar();bool f=1; for(;!isdigit(ch);ch=getchar()) f^=!(ch^'-'); for(; isdigit(ch);ch=getchar()) ret=(ret<<1)+(ret<<3)+ch-48; return f?ret:-ret; } int main(){ n=read(),m=read(),K=read(); for(int i=1;i<=n;i++) a[i]=read(); for(int i=1;i<m;i++) hsh[a[i]]++;hsh[a[0]]++;Now=0,Num=hsh[a[0]]; for(int i=m;i<=n;i++){ hsh[a[i-m]]--,hsh[a[i]]++; Num+=(a[i-m]>Now?0:-1)+(a[i]>Now?0:1); if(a[i-m]<=Now) Sum-=a[i-m]; if(a[i]<=Now) Sum+=a[i]; while(Num-hsh[Now]>K) Num-=hsh[Now],Sum-=(LL)hsh[Now]*Now,Now--; while(Num<K) Num+=hsh[++Now],Sum+=(LL)hsh[Now]*Now; Ans+=Sum-((LL)Num-K)*Now; } printf("%lld\n",Ans); return 0; }

    这道题等我后面学习一下再看吧

    C——逃离幻想乡 题目描述 “来世愿生幻想乡”,这是多少东方迷的心愿啊。

    但是……

    “来世想生在幻想乡的各位,小心到时候我的儿子看你们的本子……” 某易云音乐上的网友语惊四座。

    没想到,这件事情闹得沸沸扬扬,竟然连远在幻想乡的灵梦也知道了,于是灵梦打算带领一众妖精们逃离幻想乡,前往新的乌托邦。

    正当一众妖精再有说有笑的赶路时,在最前头的紫妈突然停了下来,原来是有一个结界拦住了去路,上面写着:

    结果妖精刚通过没多久,却发现前面有一个万丈深渊,峭壁上还有几行大字:

    妖精们啊,你们只需算出,对于一个整数m(0≤m≤n)有多少个2m在10进制下第一个数字为 L L就可以召唤深渊巨龙(神龙)通过这里。

    仗着自己开了一个红茶馆(雾),大小姐在1e-9秒内就算出了答案ans1。

    成功通过深渊后,妖精们来到了幻想乡之门前,只见门前插了3根擎天巨柱,其中最左边的柱子上有2*ans1个翡翠方块,而翡翠方块刚好从上到下依次增大且每种尺寸的翡翠方块有两块,也就是说:一共有ans1 种翡翠方块,妖精们走进一看,发现同一尺寸的翡翠方块竟然还分颜色:上面的翡翠方块为黑色,下面的翡翠方块为白色。最下面的翡翠方块上刻了一行小字:

    妖精们啊,若要出此幻想乡,你们须将所有的翡翠从左边的定海柱移至最右边的定天柱上,并且遵从以下规则:

    1.大的翡翠方块不能放在小的翡翠方块上面 2.当所有的翡翠方块移动完毕时,定天柱上的方块黑白顺序必须和定海柱上的方块黑白顺序相同

    仗着机敏的头脑,琪露诺在1e-9秒内就算出了最少的移动次数ans2

    妖精们齐心协力将所有方块移到右边的柱子上的后,突然幻想乡之门炸裂了,随后整个幻想乡的空间出现龟裂,原来,这个装置便是幻想乡的毁灭装置。

    现在灵梦她们自由了,她们可以前往她们自己的乌托邦去了。

    临走前,灵梦为了考验一下作为蒟蒻的YPC,所以就让蒟蒻YPC告诉她这一路上的ans1 ans2分别是多少,由于YPC非常蒻,所以就前来询问各位巨佬了,希望你们能求出ans1 ans2的值,注意将ans2对1000000007取模(YPC温馨提醒:模运算在Pascal下为mod,在C++下为*%*)。 输入描述: 一行2个数字n, L L。 输出描述: 第一行一个数表示ans1,第二行一个数表示ans2。

    示例1 输入 10 3 输出 1 3 ps:不多bb,上神鞪的代码

    #include<bits/stdc++.h> using namespace std; typedef long long ll; const int mod=1000000007; ll q_pow(ll a,ll b) { ll ans=1; while(b) { if(b&1) { ans=(ans*a)%mod; } a=(a*a)%mod; b>>=1; } return ans; } int main(){ ll n,l,ans1=0,ans2=0,sum1; cin>>n>>l; if(l==1)ans1=1; else ans1=0; ll s=2; for(int i=1;i<=n;i++){ ll t=s; while(t>=10)t/=10; if(t==l) ans1++; s*=2; if(s>99999999999999999LL)s/=10; } ans2=(q_pow(2,ans1)-1)*4-1; ans2%=mod; cout<<ans1<<endl<<ans2<<endl; return 0; }

    和大佬们比起来我还是太菜了,还要继续努力啊

    最新回复(0)