2020牛客寒假算法基础集训营4

链接:link
来源:牛客网

A 欧几里得

题目描述

现在,如果已知 g c d ( a , b ) gcd(a,b) gcd(a,b) 共递归了 n n n次,求所有可能的 a , b a,b a,b中满足 a > b > = 0 a>b>=0 a>b>=0 a + b a+b a+b最小的一组的 a a a b b b之和。

输入描述

第一行一个整数, T T T。接下来 T T T行一行一个整数, n n n

思路

递归0次最小的一组为 ( 1 , 0 ) (1,0) (1,0),该组往上递归一次最小的应该是 ( 2 , 1 ) (2,1) (2,1),该组往上递归最小的应该是 ( 3 , 2 ) (3,2) (3,2),依次这样递推发现应该是斐波拉契中的项数。

AC代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define rep(i,s,t) for(int i = s;i <= t;i++)
#define per(i,t,s) for(int i = t;i >= s;i--)
int t, n;
ll f[100];
int main(){
   
f[0] = 1, f[1] = 3, f[2] = 5;
rep(i,3,80) f[i] = f[i-1] + f[i-2];
   scanf("%d",&t);
   while(t--){
   
    scanf("%d",&n);
    printf("%lld\n",f[n]);
   }
   
}
//Accepted!

B 括号序列

题目描述

给定一个括号序列,只包含"{}()[]",判断合不合法

输入描述

一行一个字符串S,只包含题目中的六种括号字符
1 ≤ ∣ S ∣ ≤ 1000000 1≤∣S∣≤1000000 1S1000000

思路

用栈或者递推都可以

AC代码

#include<stdio.h>
#include<algorithm>
#include<string.h>
#define maxn 1000005
#define ll long long
using namespace std;
char str[maxn];
char p[maxn];
int len,cnt;
int sta[500];
int checkr[500];
int main(){
   
    scanf("%s",&str);
    sta[')']=1,sta[']']=2,sta['}']=3;
    sta['(']=1,sta['[']=2,sta['{']=3;
    checkr[')']=1,checkr[']']=1,checkr['}']=1;
    len=strlen(str);
    if(len==0)printf("Yes\n");
    else{
   
        int ans=1;
        for(int i=0;i<len;i++){
   
            if(cnt==0){
   
                if(checkr[str[i]]==1){
   
                    ans=0;
                    break;
                }
                else {
   
                    p[++cnt]=str[i];
                }
            }
            else{
   
                if(checkr[str[i]]==0)p[++cnt]=str[i];
                else {
   
                    if(sta[p[cnt]]==sta[str[i]])cnt--;
                    else {
   
                        ans=0;
                        break;
                    }
                }
            }
        }
        if(ans==1&&cnt==0)printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

C 子段乘积

题目描述

给出一个长度为 n n n 的数列 a 1 , a 2 , … , a n a_1,a_2,…,a_n a1,a2,,an,求其长度为 k k k 的连续子段的乘积对 998244353 取模余数的最大值。

输入描述

第一行两个整数 n , k n,k n,k
第二行n个整数, a 1 , a 2 , … , a n a_1,a_2,…,a_n a1,a2,,an​。

思路

线段树直接暴力算,复杂度是 l o g 2 n ∗ ( n − k + 1 ) {log}_2^n*(n-k+1) log2n(nk+1)

AC代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define rep(i,s,t) for(int i = s;i <= t;i++)
#define per(i,t,s) for(int i = t;i >= s;i--)
#define ls(x) x<<1
#define rs(x) ((x<<1)|1) 
#define maxn 200005 
#define mod 998244353LL
ll a[maxn],  t[maxn<<2];
int n, k;
void up(int x){
   
 t[x] = t[ls(x)]*t[rs(x)]%mod;
}
void build(int x,int l,int r){
   
 if(l == r){
   
  t[x] = a[l];
  return; 
 }
 int mid = (l+r)>>1;
 build(ls(x),l,mid);
 build(rs(x),mid+1,r);
 up(x);
 
}
ll query(int x,int l,int r,int l0,int r0){
   
 if(l >= l0 && r <= r0) return t[x];
 int mid = (l + r)>>1;
 ll res = 1;
 if(l0 <= mid) res = res*query(ls(x),l,mid,l0,r0)%mod;
 if(r0 > mid) res = res*query(rs(x),mid+1,r,
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值