链接: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 1≤∣S∣≤1000000
思路
用栈或者递推都可以
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∗(n−k+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,