牛客练习赛79 总结
A 炼金术师
离散化一下排个序取最值即可
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int N=1e6+10; int a[N],x[N],y[N],n,m,ans; int main() { scanf("%d",&n); if (n==0) return printf("0"),0; for (int i=1;i<=n;i++) scanf("%d",&x[i]),y[i]=x[i]; sort(x+1,x+n+1);m=unique(x+1,x+n+1)-x-1; for (int i=1,j;i<=n;i++) a[j=lower_bound(x+1,x+m+1,y[i])-x]=max(a[j],i); for (int i=m;i;i--) a[i]=max(a[i],a[i+1]); ans=1;for (int i=1;i<m;i++) if (a[i]!=a[i+1]) ans++; printf("%d\n",ans); }
B 刀工对决
各自除掉最大公因数以后如果仍存在非 3,5 的因数则必不行
然后分类讨论,如果剩下因子的 3 和 5 分别在不同数上, 则考虑若 3 的个数大于 5 ,则只需要消耗 3 的个数刀( 5 变成 3 ,3 减到 5 的个数)
若 3 的个数小于 5 ,则需要 5 的个数+ 5的个数 - 3 的个数
如果在同一个数上就是 5 的个数*2 + 3 的个数
#include <iostream> #include <cstdio> using namespace std; int n,a,b,gcd,ans,ta,tb,fa,fb; int GCD(int a,int b) {return !a?b:GCD(b%a,a);} int main() { for (scanf("%d",&n);n;n--) { scanf("%d%d",&a,&b);gcd=GCD(a,b);ta=tb=fa=fb=0;a/=gcd;b/=gcd; while (a>1) { if (a%3==0) {a/=3,ta++;continue;} if (a%5==0) {a/=5,fa++;continue;} return printf("-1"),0; } while (b>1) { if (b%3==0) {b/=3,tb++;continue;} if (b%5==0) {b/=5,fb++;continue;} return printf("-1"),0; } if (fa<fb) swap(ta,tb),swap(fa,fb); if (tb-ta>=fa-fb) ans+=tb-ta; else ans+=(fa-fb)*2+ta-tb; } printf("%d\n",ans); }
C 小G的GCD
不知道怎么A的,乱搞了个结论,不会证
#include <iostream> #include <cstdio> #include <cmath> using namespace std; typedef long long ll; ll n,a,b,ans; int main() { scanf("%lld",&n);a=b=1; if (n==1) return printf("2"),0; while (a<=n) { if (a>b) swap(a,b); a+=b;ans++; } printf("%lld",ans+1); }
D 回文字D
马拉车搞一下,然后讨论 d 的奇偶性,有显然的 DP
一开始在马拉车的双倍字符串上搞得太复杂了,罚了好多时
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int N=1e7+10; int p[2*N],n,m,d,f[N]; char s[N],t[2*N]; void Manacher() { int rig=0,i=0;p[0]=1; for (int j=1;j<=m;j++) { if (rig<j) p[j]=1; else p[j]=min(p[2*i-j],rig-j+1); while (t[j+p[j]]==t[j-p[j]]) p[j]++; if (j+p[j]-1>rig) rig=j+p[j]-1,i=j; } } int main() { scanf("%d%d",&n,&d); if (d>n) return printf("1"),0; scanf("%s",s+1); t[0]='$';for (int i=1;i<=n;i++) t[++m]='#',t[++m]=s[i]; t[++m]='#';t[++m]='@'; Manacher(); for (int i=1;i<d;i++) f[i]=1; for (int i=d;i<=n;i++) { f[i]=2147483647; if (p[2*(i-d/2)+(d%2==0)]>d) f[i]=min(p[2*(i-d/2-1)+(d%2==0)]>d?f[i-1]:n+1,f[i-d]+1); f[i]=min(f[i],f[i-d+1]+1); } printf("%d",f[n]); }
在日渐沉没的世界里,我发现了你。