zoukankan      html  css  js  c++  java
  • 2019-8-13 考试总结

    A. count

    在我看来不是个水题。。

    想了好长时间,想到和正解差不多的思路,

    本质应该是个贪心。

    每次递归求每个节点的$size$,如果这个节点的$size$是现在枚举的每块的大小$L$,那么它的$size$置为$0$,

    看一下到根节点的时候$size$是否为$0$。

    思路应该是对的。

    正解要好一点,看一下有多少节点的$size$可以整除$L$,如果这个数大于等于$frac{n}{L}$,则$ans++$。

    丑陋的代码:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #define Reg register
    #define Maxn 1000050
    using namespace std;
    int n,tot,ans,top,anp,now,siz[Maxn],fir[Maxn],vis[Maxn],num[Maxn];
    struct Tu {int st,ed,next;} lian[Maxn*2];
    void add(int x,int y)
    {
        lian[++tot].st=x;
        lian[tot].ed=y;
        lian[tot].next=fir[x];
        fir[x]=tot;
        return;
    }
    void dfs(int x,int fa)
    {
        siz[x]=1;
        for(Reg int i=fir[x];i;i=lian[i].next)
        {
            if(lian[i].ed==fa) continue;
            dfs(lian[i].ed,x);
            siz[x]+=siz[lian[i].ed];
        }
        ++num[siz[x]];
        return;
    }
    int main()
    {
        scanf("%d",&n);
        for(Reg int i=1,x,y;i<=n-1;++i)
        {
            scanf("%d%d",&x,&y);
            add(x,y); add(y,x);
        }
        dfs(1,0);
        for(Reg int i=n;i>=1;--i)
        {
            if(n%i!=0) continue;
            int p=0;
            for(Reg int j=1;i*j<=n;++j) p+=num[i*j];
            if(p>=n/i) ++ans;
        }
        printf("%d",ans);
        return 0;
    }
    View Code

    B. Dinner

    好吧,它是个圆桌。。

    上来看完$T1$没啥思路然后滚来看$T2$,乍一看二分答案水题。。

    结果我就$WA0$了。

    还要枚举一个起点,暴力的话时间复杂度$O(n^2logn)$。

    承受不住。

    根据$starsing$大神的推导,只要枚举$1$号点可以一次到达的点即可。

    因为如果把这个点之后的点当作起点,就相当于把它作为中间的断点,把$1$能到达的某个点当作起点,因为是个圆桌。

    丑陋的代码:

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #define Maxn 50050
    #define Reg register
    #define INF 0x7ffffff
    #define int long long
    #define _min(x,y) ((x)<(y)?(x):(y))
    #define _max(x,y) ((x)>(y)?(x):(y))
    #define _abs(x) ((x)<0?(-1*(x)):(x))
    using namespace std;
    int n,m,mxx,mnn,T[Maxn*2],sum[Maxn*2],nxt[Maxn*2][20],vis[Maxn*2];
    bool judge(int t)
    {
        int p=1;
        while(p+1<=2*n&&sum[p+1]-sum[1]<=t) ++p;
        for(Reg int s=1;s<=p;++s)
        {
            int p=0,now=s;
            for(Reg int i=1;i<=m;++i)
                now=upper_bound(sum+i,sum+n*2+1,sum[now]+t)-sum-1;
            if(now>=s+n) return 1;
        }
        return 0;
    }
    int erfen(int l,int r)
    {
        if(l==r) return l;
        int mid=(l+r)>>1;
        if(judge(mid)) return erfen(l,mid);
        else return erfen(mid+1,r);
    }
    signed main()
    {
        scanf("%lld%lld",&n,&m);
        for(Reg int i=1;i<=n;++i)
        {
            scanf("%lld",&T[i]);
            sum[i]=sum[i-1]+T[i];
            mxx+=T[i];
            mnn=_max(mnn,T[i]);
        }
        for(Reg int i=n+1;i<=n*2;++i)
        {
            T[i]=T[i-n];
            sum[i]=sum[i-1]+T[i];
        }
        if(m>=n) printf("%lld
    ",mnn);
        else
        {
            int ans=erfen(mnn,mxx);
            printf("%lld
    ",ans);
        }
        return 0;
    }
    View Code

    C. chess

    总结:

    怎么说呢,考试一次高一次低,起伏有点大。。

    可能是我太菜了。。。

    总体来说没上次考得好,主要是$T2$。

    当时审题可能有问题,而且非常想当然,以为完全能过这道题。。

    样例$2$: $4$ $2$     $1$ $2$ $3$ $4$。

    输出: $5$

    样例$2$错误解释:

    把第三个人分开,分成一个$1$和一个$2$。

    然后左边就成了$1+2+2=5$,右边也是$1+4=5$。

    正确解释:

    从第二个人开始,然后$2+3=5$,$4+1=5$。

    审题仔细,不要想当然。

    心态的话,应该还不错。

    最后$60+0+30=90$。

    没什么水平。。。

  • 相关阅读:
    Android 开发 深入理解Handler、Looper、Messagequeue 转载
    Android 开发 Handler的基本使用
    Java 学习 注解
    Android 开发 AlarmManager 定时器
    Android 开发 框架系列 百度语音合成
    Android 开发 框架系列 Google的ORM框架 Room
    Android 开发 VectorDrawable 矢量图 (三)矢量图动画
    Android 开发 VectorDrawable 矢量图 (二)了解矢量图属性与绘制
    Android 开发 VectorDrawable 矢量图 (一)了解Android矢量图与获取矢量图
    Android 开发 知晓各种id信息 获取线程ID、activityID、内核ID
  • 原文地址:https://www.cnblogs.com/Milk-Feng/p/11345142.html
Copyright © 2011-2022 走看看