• 魔术球问题


    传送门:

    题解区的玄学公式:球的个数:(n*(n+2)+(n&1)-2)/2

    既然能直接求出球的个数那么就会有贪心法emmm

    #include <cstdlib>
    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <queue>
    #include <cmath>
    using namespace std;
    #define ll long long
    #define re register
    const int N=1e7+10;
    const int inf=1e9;
    inline void read(int &a)
    {
        a=0;
        int d=1;
        char ch;
        while(ch=getchar(),ch>'9'||ch<'0')
            if(ch=='-')
                d=-1;
        a=ch^48;
        while(ch=getchar(),ch>='0'&&ch<='9')
            a=(a<<3)+(a<<1)+(ch^48);
        a*=d;
    }
    int a[60][60];
    int f(int x){return x*x;}
    int main()
    {
        int n,m;
        read(n);
        m=(n*(n+2)+(n&1)-2)/2;
        printf("%d
    ",m);
        for(re int i=1;i<=m;i++)
            for(re int j=1;j<=n;j++)
            {
                int x=a[j][a[j][0]];
                if(!x||f(int(sqrt(x+i)))==x+i)
                {
                    a[j][++a[j][0]]=i;
                    break;
                }
            }
        for(re int i=1;i<=n;i++)
        {
            for(re int j=1;j<=a[i][0];j++)
                printf("%d ",a[i][j]);
            putchar('
    ');
        }
        return 0;
    }

    但是作为一道网络流24题的题目,我觉得应该要用网络流的方法写才能锻炼自己,如果对最大流模板熟悉,那么这道题的难点只是建图。

    这题只要把一个点分割成两个点,然后建图就ok了

    #include <cstdlib>
    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <queue>
    #include <cmath>
    using namespace std;
    #define ll long long
    #define re register
    const int N=1e6+10;
    const int inf=1e9;
    inline void read(int &a)
    {
        a=0;
        int d=1;
        char ch;
        while(ch=getchar(),ch>'9'||ch<'0')
            if(ch=='-')
                d=-1;
        a=ch^48;
        while(ch=getchar(),ch>='0'&&ch<='9')
            a=(a<<3)+(a<<1)+(ch^48);
        a*=d;
    }
    struct note
    {
        int next,v,dis;
    }edge[N];
    int cnt=-1,head[N],n,dep[N],p[60],nxt[N];
    bool vis[N];
    inline void add(int u,int v,int dis)
    {
        edge[++cnt].next=head[u];
        edge[cnt].v=v;
        edge[cnt].dis=dis;
        head[u]=cnt;
        edge[++cnt].next=head[v];
        edge[cnt].v=u;
        edge[cnt].dis=0;
        head[v]=cnt;
    }
    queue <int> q;
    inline bool bfs(int s,int t)
    {
        memset(dep,0x7f,sizeof(dep));
        while(!q.empty())
            q.pop();
        dep[s]=0;
        q.push(s);
        while(!q.empty())
        {
            int now=q.front();
            q.pop();
            for(re int i=head[now];i!=-1;i=edge[i].next)
            {
                if(dep[edge[i].v]>inf&&edge[i].dis)
                    dep[edge[i].v]=dep[now]+1,q.push(edge[i].v);
            }
        }
        if(dep[t]<inf)
            return 1;
        return 0;
    }
    inline int dfs(int now,int t,int limit)
    {
        if(now==t)
            return limit;
        for(re int i=head[now];i!=-1;i=edge[i].next)
        {
            if((dep[edge[i].v]==dep[now]+1)&&edge[i].dis)
            {
                int f=dfs(edge[i].v,t,min(limit,edge[i].dis));
                if(f>0)
                {
                    edge[i].dis-=f;
                    edge[i^1].dis+=f;
                    if(now!=0&&edge[i].v!=N-1)
                        nxt[now>>1]=edge[i].v>>1;
                    return f;
                }
            }
        }
        return 0;
    }
    inline int dinic(int s,int t)
    {
        int flow=0;
        while(bfs(s,t))
        {
            while(int di=dfs(s,t,inf))
                flow+=di;
        }
        return flow;
    }
    int main()
    {
        memset(head,0xff,sizeof(head));
        int s=0,t=N-1,k;
        n=0;
        read(k);
        int now=0;
        while(now<=k)
        {
            n++;
            add(s,(n<<1),1);
            add((n<<1)|1,t,1);
            for(re int i=sqrt(n)+1;i*i<(n<<1);i++)
                add((i*i-n)<<1,(n<<1)|1,1);
            int x=dinic(s,t);
            if(!x)
                p[++now]=n;
        }
        printf("%d
    ",n-1);
        for(re int i=1;i<=k;i++)
        {
            if(vis[p[i]])
                continue;
            int x=p[i];
            vis[x]=1;
            while(x!=0)
            {
                printf("%d ",x);
                x=nxt[x];
                vis[x]=1;
            }
            putchar('
    ');
        }
        return 0;
    }
  • 相关阅读:
    从句分析
    artDialog ( v 6.0.2 ) content 参数引入页面 html 内容
    Java实现 LeetCode 13 罗马数字转整数
    Java实现 LeetCode 13 罗马数字转整数
    Java实现 LeetCode 13 罗马数字转整数
    Java实现 LeetCode 12 整数转罗马数字
    Java实现 LeetCode 12 整数转罗马数字
    Java实现 LeetCode 12 整数转罗马数字
    Java实现 LeetCode 11 盛最多水的容器
    Java实现 LeetCode 11 盛最多水的容器
  • 原文地址:https://www.cnblogs.com/acm1ruoji/p/11045105.html
Copyright © 2020-2023  润新知