• 牛客OI测试赛1


    题目链接: https://www.nowcoder.com/acm/contest/181#question

    A.斐波拉契

    求$f[n-1]*f[n+1]-f[n]^2$,$f[n]$为斐波拉契数列第$n$项

    算一下前几项不难发现答案为$(-1)^n$,下面用数学归纳法证明一下:

    $n=2$时,猜想成立

    假设$n=k$时猜想成立,即$f[k-1]*f[k+1]-f[k]^2=(-1)^k$

    当$n=k$时,$f[k]f[k+2]-f[k+1]^2=f[k](f[k+1]+f[k])-f[k+1]*(f[k]+f[k-1])=f[k]^2-f[k-1]f[k+1]=(-1)^{k+1}$

    得证

    #include <cstdio>
    #include <algorithm>
    #include<vector>
    #include<iostream>
    #include<cstring>
    char s[1000005];
    using namespace std;
    int main(){
        scanf("%s",s);
        int l=strlen(s);
        int z=s[l-1]-'0';
        if(z%2==0)
            cout<<1<<endl;
        else cout<<-1<<endl;
    }
    

    B.送分题

    #include <cstdio>
    #include <algorithm>
    #include<vector>
    #include<iostream>
    using namespace std;
    bool vis[10005];
    int a[10005];
    vector<int> ans;
    int main(){
        long long  a,b;
        cin>>a>>b;
        cout<<a+b<<endl;
    }
    

    C.序列

    暴力就好,先求出该序列每处的前缀和,用map表示该前缀和存在,对于每次查询,先判断k之前是否查询过,查询过则不用判断,再判断序列和是否是k的倍数,否则,对于$1(sum/z)~k(sum/z)$的前缀和是否都存在

    #include <cstdio>
    #include <algorithm>
    #include<vector>
    #include<iostream>
    #include<cstring>
    #include<map>
    using namespace std;
    typedef long long ll;
    const int maxn=100005;
    int ans[maxn];
    
    ll a[maxn];
    map<ll,int> mp;
    
    int main(){
        int n,q;
        scanf("%d%d",&n,&q);
        ll sum=0;
        for(int i=1;i<=n;i++){
            scanf("%lld",&a[i]);
            sum+=a[i];
            mp[sum]=1;
        }
        for(int i=1;i<=q;i++){
            int z;
            scanf("%d",&z);
            if(z>n||sum%z!=0||ans[z]==2){
                printf("No
    ");
                continue;
            }
    
            if(ans[z]==1){
                printf("Yes
    ");
                continue;
            }
            for(int i=1;i*(sum/z)<sum;i++){
                if(mp[i*(sum/z)]!=1){
                    printf("No
    ");
                    ans[z]=2;
                    break;
                }
            }
            if(ans[z]!=2){
                printf("Yes
    ");
                ans[z]=1;
            }
        }
    }

    D.小叶的巡查

    求下直径就好了

    #include <cstdio>
    #include <algorithm>
    #include<vector>
    #include<iostream>
    #include<cstring>
    using namespace std;
    const int maxn=100005;
    vector< pair<int,int> > g[maxn];
    int d[maxn];
    bool vis[maxn];
    void dfs(int u){
        vis[u]=1;
        for(int i=0;i<g[u].size();i++){
            int v=g[u][i].first;
            if(!vis[v]){
                d[v]=d[u]+g[u][i].second;
                dfs(v);
            }
        }
    }
    int main(){
        int n;
        scanf("%d",&n);
        for(int i=1;i<n;i++){
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            g[x].push_back(make_pair(y,z));
            g[y].push_back(make_pair(x,z));
        }
       // cout<<-1<<endl;
        dfs(1);
        int cnt;
        long long dmax=0;
        for(int i=1;i<=n;i++){
            if(d[i]>dmax){
                dmax=d[i];
                cnt=i;
            }
            vis[i]=0;
            d[i]=0;
        }
        dmax=0;
        dfs(cnt);
        for(int i=1;i<=n;i++){
            if(d[i]>dmax){
                dmax=d[i];
            }
        }
        cout<<dmax*10+(1+dmax)*dmax/2<<endl;
    }

    E.旅行青蛙

    最长上升子序列,但是感觉题意有问题,题目的描述应该是最长不上升子序列233,n比较大,用$O(n*log n)$的写法

    #include <cstdio>
    #include <algorithm>
    #include<vector>
    #include<iostream>
    #include<cstring>
    using namespace std;
    const int maxn=100005;
    int dp[maxn];
    int a[maxn];
    int n;
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        int cnt=0;
        dp[0]=-1e9;
        for(int i=1;i<=n;i++){
            if(a[i]>=dp[cnt]){
                dp[++cnt]=a[i];
            }
            else {
                int z=upper_bound(dp+1,dp+1+cnt,a[i])-dp;
                dp[z]=a[i];
            }
        }
        cout<<cnt<<endl;
    }
    

    F.子序列

    由题意知,答案与序列的顺序无关,故先将序列排个序,对于序列中的第i个数,需要相乘的次数为$C{n-1}^{k-1}-C{i-1}^{k-1}-C_{n-i}^{k-1}$。又1e9+7为素数,根据欧拉公式$a^{p-1}equiv1mod p$

    即可得出答案

    #include <cstdio>
    #include <algorithm>
    #include<vector>
    #include<iostream>
    #include<cstring>
    #include<map>
    using namespace std;
    typedef long long ll;
    const ll mod=1e9+7;
    const int maxn=1005;
    
    ll pmod(ll a,ll b){
        if(a==0) return 0;
        if(b==0) return 1;
        if(b==1) return a%mod;
        ll ans=pmod(a,b/2);
        ans=ans*ans%mod;
        if(b&1)
            return ans*a%mod;
        return ans;
    }
    ll a[maxn];
    ll c[maxn][maxn];
    int main(){
        for(int i=0;i<=1000;i++)
            c[i][0]=1;
        c[1][1]=1;
        for(int i=1;i<=1000;i++)
            c[i][i]=1;
        for(int i=1;i<=1000;i++)
            for(int j=1;j<i;j++)
            c[i][j]=(c[i-1][j]+c[i-1][j-1])%(mod-1);
        int t;
        scanf("%d",&t);
        while(t--){
            int n,k;
            scanf("%d%d",&n,&k);
            for(int i=1;i<=n;i++)
                scanf("%lld",&a[i]);
            sort(a+1,a+1+n);
            ll ans=1;
            for(int i=2;i<n;i++){
                ll z=c[n-1][k-1];
                if(n-i>=k-1)
                    z-=c[n-i][k-1];
                if(i-1>=k-1)
                    z-=c[i-1][k-1];
                z=((z)%(mod-1)+mod-1)%(mod-1);
                z=pmod(a[i],z);
                ans=ans*z%mod;
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    

      

  • 相关阅读:
    SDWebImage内部实现过程
    物理仿真元素
    物理仿真元素
    运行时案例
    使用运行时交换我们自定义的方法
    运行时交换系统方法
    HTML 钟表 小时钟
    JS小游戏寻找房祖名
    程序启动的完整过程
    ApplicationDelegate里的方法
  • 原文地址:https://www.cnblogs.com/dlutjwh/p/10976341.html
Copyright © 2020-2023  润新知