zoukankan      html  css  js  c++  java
  • NOIP2018

    Day1

    T1 Road

    贪心:差分

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    #define Maxn 100100
    int n,ans;
    int a[Maxn];
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        for(int i=1;i<=n;i++)
        {
            if(a[i]>a[i-1])ans+=a[i]-a[i-1];
        }
        printf("%d",ans);
        return 0;
    }
    

    T2 Money

    完全背包

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    #define Maxn 110
    #define R register
    int n,T;
    int tot=0;
    int f[25100]={};
    int a[Maxn];
    int b[Maxn];
    bool cmp(int x,int y){return x<y;}
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
        tot=0;
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        memset(f,0,sizeof(f));
        scanf("%d",&n);
        for(R int i=1;i<=n;i++)scanf("%d",&a[i]);
        sort(a+1,a+n+1,cmp);
        f[0]=1;
        for(R int i=1;i<=n;i++)
        {
            for(R int j=1;j<=tot;j++)
            {
                for(R int k=a[i-1];k<=a[i];k++)
                    f[k]+=f[k-b[j]];
            }
            if(f[a[i]]==0)
            {
                b[++tot]=a[i];
            }
        }
        printf("%d
    ",tot);
        }
        return 0;
    }
    

    T3 Track

    这道题考察了对于dp状态的设计(当一些dp状态不好设计的时候,不如直接按题目要求设计)

    以及从小数据入手,再到大数据的思想

    不会用容器,但学到了很巧妙的设初值的方法,代码实现较难

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    #define Maxn 500100
    #define R register
    int n,m;
    int fir[Maxn],nxt[Maxn*2],vv[Maxn*2],edge[Maxn*2];
    int tot=0;
    int ans=0;
    int s[Maxn],tag[Maxn],dp[Maxn];
    void add(int x,int y,int z)
    {
        nxt[++tot]=fir[x];
        fir[x]=tot;
        vv[tot]=y;
        edge[tot]=z;
    }
    void dfs(int u,int fa,int x)
    {
        int cnt=0;
        for(R int i=fir[u];i;i=nxt[i])
        {
            int v=vv[i];
            if(v==fa)continue;
            dfs(v,u,x);
        }
        for(R int i=fir[u];i;i=nxt[i])
        {
            int v=vv[i];
            if(v==fa)continue;
            s[++cnt]=dp[v]+edge[i];
        }
        int maxx=0;int num=0;
        sort(s+1,s+cnt+1);
        for(R int i=cnt;i>=1&&s[i]>=x;i--)cnt--,ans++;
        for(R int i=1;i<=cnt;i++)
        {
            if(tag[i]!=u)
            {
                int l=i+1,r=cnt,tmp=cnt+1;
                while(l<=r)
                {
                    int mid=(l+r)>>1;
                    if(s[i]+s[mid]>=x)
                        tmp=mid,r=mid-1;
                    else l=mid+1;
                }
                while(tag[tmp]==u&&tmp<=cnt)tmp++;
                if(tmp<=cnt)
                {
                    tag[i]=u;tag[tmp]=u;ans++;
                }
            }
        }
        for(R int i=cnt;i>=1;i--)
        {
            if(tag[i]!=u)
            {
                dp[u]=s[i];break;
            }
        }
        return;
    }
    int check(int x)
    {
        ans=0;
        dfs(1,0,x);
        if(ans>=m)return 1;else return 0;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        int c=0;
        for(R int i=1;i<n;i++)
        {
            int x,y,z;scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);add(y,x,z);c+=z;
        }
        int l=0,r=c/m;
        int anss=0;
        while(l<=r)
        {
            memset(dp,0,sizeof(dp));
            memset(tag,0,sizeof(tag));
            int mid=(l+r)>>1;
            if(check(mid)==1)
            {
                anss=mid;l=mid+1;
            }
            else r=mid-1;
        }
        printf("%d
    ",anss);
        return 0;
    }
    

    Day 2

    T1 Travel

    很朴素的基环树

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    #define Maxn 5010
    #define R register
    int n,m;
    int fir[Maxn],nxt[Maxn*2],vv[Maxn*2];
    int tot=0;
    int rt1,rt2;
    int num=0;
    int fa[Maxn],vis[Maxn]={},circle[Maxn],cnt=0,found=0;
    void add(int x,int y)
    {
        nxt[++tot]=fir[x];
        fir[x]=tot;
        vv[tot]=y;
    }
    int s[Maxn][Maxn],tail[Maxn],ans1[Maxn],ans2[Maxn];
    void dfs1(int u,int fa)
    {
        printf("%d ",u);
        for(R int i=1;i<=tail[u];i++)
        {
            if(s[u][i]==fa)continue;
            dfs1(s[u][i],u);
        }
        return;
    }
    void dfs2(int u,int fa)
    {
        ans2[++num]=u;
        for(R int i=1;i<=tail[u];i++)
        {
            int v=s[u][i];
            if((s[u][i]==fa)||(u==rt1&&v==rt2)||(u==rt2&&v==rt1))continue;
            dfs2(s[u][i],u);
        }
        return;
    }
    void find_curcle(int u,int F)
    {
        fa[u]=F;
        vis[u]=1;
        for(R int i=fir[u];i;i=nxt[i])
        {
            int v=vv[i];
            if(v==F)
            {
                F=-1;
                continue;
            }
            if(!vis[v])find_curcle(v,u);
            else
            {
                found=1;
                circle[cnt=1]=u;
                int tmp=u;
                do
                {
                    tmp=fa[tmp];
                    circle[++cnt]=tmp;
                }while(tmp!=v);
                return;
            }
            if(found==1)return;
        }
    }
    void solve()
    {
        circle[cnt+1]=circle[1];
        memset(ans1,0x3f3f3f3f,sizeof(ans1));
        for(R int i=1;i<=cnt;i++)
        {
            rt1=circle[i];rt2=circle[i+1];
            int pd=0;num=0;
            dfs2(1,0);
            for(R int j=1;j<=n;j++)
            {
                if(pd!=0)break;
                for(R int k=1;k<=n;k++)
                {
                    if(ans2[k]<ans1[k]){pd=2;break;}
                    if(ans2[k]>ans1[k]){pd=1;break;}
                }
            }
            if(pd==2)
            {
                for(int j=1;j<=n;j++)ans1[j]=ans2[j];
            }
        }
    }
    int main()
    {
      //  freopen("travel.in","r",stdin);
       // freopen("travel.out","w",stdout);
        scanf("%d%d",&n,&m);
        for(R int i=1;i<=m;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            tail[x]++;tail[y]++;
            s[x][tail[x]]=y;s[y][tail[y]]=x;
            add(x,y);add(y,x);
        }
        int a[Maxn];
        for(R int i=1;i<=n;i++)
        {
            for(R int j=1;j<=tail[i];j++)
            {
                a[j]=s[i][j];
            }
            sort(a+1,a+tail[i]+1);
            for(R int j=1;j<=tail[i];j++)s[i][j]=a[j];
        }
       if(m==n-1)
            dfs1(1,0);
        else
        {
            find_curcle(1,0);
            solve();
        for(R int i=1;i<=n;i++)printf("%d ",ans1[i]);
        }
        return 0;
    }
    

    T2、T3待补

    还是很有收获吧,同时也感受到了差距,,

  • 相关阅读:
    sublime Text3插件无法安装解决方法(提示There are no packages available installation)
    扫码消费数量栏点击可编辑,失去焦点还原样式
    浏览器内核
    js全选checkbox框
    word-wrap: break-word;与word-break: break-all;文本自动换行
    含加减的输入框
    linux ,mac连接, git pull error, chmod修改文件的权限/chown修改文件和目录的所有者
    vue修改对象的属性值后页面不重新渲染
    jsp 判断时间大小
    利用js实现 禁用浏览器后退| 去除上一个历史记录链接
  • 原文地址:https://www.cnblogs.com/Akaina/p/11296393.html
Copyright © 2011-2022 走看看