牛客网 OI 赛制测试赛

比赛链接:这里写链接内容
A 斐波那契
链接:https://www.nowcoder.com/acm/contest/181/A
来源:牛客网

设f[i]表示斐波那契数论的第i项
f[1]=1,f[2] =1,f[i] = f[i - 1] + f[i - 2]
给定一个n

附题解
这里写图片描述

#include<iostream>
#include<cstdio>
using namespace std;

int main(){
    string str;
    cin>>str;
    int len=str.length();
    if((str[len-1]-'0')%2==0){
        printf("1\n");
    }
    else{
        printf("-1\n");
    }
}

B 就不放了
C 序列
链接:https://www.nowcoder.com/acm/contest/181/C
来源:牛客网

小a有n个数,他想把他们划分为连续的权值相等的k段,但他不知道这是否可行。
每个数都必须被划分
这个问题对他来说太难了,于是他把这个问题丢给了你。

暴力可过,就是首先要满足的要求肯定是总和sum%k是否等于0,然后暴力枚举,有k个就行(在总和是k的倍数的情况下)

    k = 0;
        for(int j = 1; j <= N; j++) {
            cur += a[j];
            if(cur == sum / i)  cur=0,k++;
        }
        ans[i] =  (k == i);

但是二分的方法更有前途(蒟蒻拙见,大佬见谅呜呜呜)
这里贴一位大佬(牛客网流木)的二分(老实说我写二分真要命)

#include<bits/stdc++.h>
const int M=1000005;

typedef long long ll;
using namespace std;
ll a[M];
int n,q;

int main(){
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++)scanf("%lld",&a[i]),a[i]+=a[i-1];
    while(q--){
        ll x;
        scanf("%lld",&x);
        if(a[n]%x)puts("No");
        else{
            int f=1;
            for(int i=1;i<=x-1;i++){
                int w=lower_bound(a+1,a+n+1,i*a[n]/x)-a;

                if(a[w]!=i*a[n]/x){f=0;puts("No");break;}
            }
            if(f)puts("Yes");
        }
    }
    return 0;
}

D 小叶的巡查

就是一道树的直径题,开始把树的直径看错了,没敢写,what
树的直径就是双重dfs ,这题小心数据int会爆掉

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int MAXN=100001;
struct node{
    int to,next,w;

}edge[MAXN];
int head[MAXN];
int num;
int n,m;
typedef long long ll;
void add_edge(int u,int v,int w){
    edge[++num].next=head[u];
    edge[num].to=v;
    edge[num].w=w;
    head[u]=num;

}
int dp[MAXN];
ll ans=0;
int ed=0;
void dfs(int u,int fa,ll now)
{
    if(now>ans)
    {
        ans=now;
        ed=u;
    }
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        if(edge[i].to!=fa)
            dfs(edge[i].to,u,now+edge[i].w);
    }
}
int main(){

     scanf("%d",&n);
     memset(head,-1,sizeof(head));
     for(int i=1;i<n;i++)
     {
         int u,v,w;
         scanf("%d%d%d",&u,&v,&w);
         add_edge(u,v,w);
         add_edge(v,u,w);
     }
     dfs(1,0,0);
     dfs(ed,0,0);
     printf("%lld",ans*10+(1+ans)*ans/2);
    return 0;
}

E 旅行青蛙
就是一道最长不下降子序列的裸题
开始我写的是最长上升子序列,没看清题目,纳尼。

#include<iostream>
#include<cstdio>
using namespace std;
const int N=23333+10;
int dp[N],a[N];

int binarysearch(int k,int len){
    int l=0,r=len-1;
    while(l<=r) {
        int mid=(l+r)>>1;
        if(k<dp[mid]) {
            r=mid-1;
        } else {
            l=mid+1;
        }
    }
    return l;
}
int main() {
    int n,len;
    scanf("%d",&n);

    for(int i=0; i<n; i++) {
        scanf("%d",&a[i]);
    }
    len=0;
    for(int i=0;i<n;i++){
        int t=binarysearch(a[i],len);
        if(t>=len) len++;
        dp[t]=a[i];
    }
     printf("%d\n",len);
}

测试赛果然良心,除了F题,其他的都一眼可以看出解法,嗯,(敲码另说)呜呜呜呜

最后一题放一下题解,和大佬的代码记录一下吧,
这里写图片描述

贴的是牛客网applese大佬的代码:


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
bool Finish_read;
template<class T>inline void read(T &x){Finish_read=0;x=0;int f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();x*=f;Finish_read=1;}
template<class T>inline void print(T x){if(x/10!=0)print(x/10);putchar(x%10+'0');}
template<class T>inline void writeln(T x){if(x<0)putchar('-');x=abs(x);print(x);putchar('\n');}
template<class T>inline void write(T x){if(x<0)putchar('-');x=abs(x);print(x);}
/*================Header Template==============*/
const int mod=1e9+7;
namespace {
    inline int Add(const int &x,const int &y,const int &p) {
        int res=x+y;
        if(res>=p)
            res-=p;
        return res;
    }
    inline int Sub(const int &x,const int &y,const int &p) {
        int res=x-y;
        if(res<0)
            res+=p;
        return res;
    }
    inline int Mul(const int &x,const int &y,const int &p) {
        return 1ll*x*y%p;
    }
    inline int Pow(int x,int y,const int &p) {
        int res=1;
        while(y) {
            if(y&1)
                res=1ll*res*x%p;
            x=1ll*x*x%p;
            y>>=1;
        }
        return res;
    }
}
int T,n,k,val[1005],C[1005][1005];
int main() {
    for(int i=0;i<=1000;++i) {
        C[i][0]=1;
        for(int j=1;j<=i;++j)
            C[i][j]=Add(C[i-1][j-1],C[i-1][j],mod-1);
    }
    read(T);
    while(T--) {
        read(n),read(k);
        for(int i=1;i<=n;++i)
            read(val[i]);
        if(k<=2) {
            puts("1");
            continue;
        }
        sort(val+1,val+n+1);
        int ans=1;
        for(int i=1;i<=n;++i)
            ans=Mul(ans,Pow(val[i],Sub(C[n-1][k-1],Add(C[i-1][k-1],C[n-i][k-1],mod-1),mod-1),mod),mod);
        printf("%d\n",ans);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_37774171/article/details/82223918