zoukankan      html  css  js  c++  java
  • 魔术球问题

    传送门:

    题解区的玄学公式:球的个数:(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;
    }
  • 相关阅读:
    Android 中的通知
    Android 画图之Matrix(二)
    Android 画图之 Matrix(一)
    Android 实现书籍翻页效果(转载链接)
    Android 基于TranslateAnimation 的动画动态菜单(非系统menu菜单)
    Activity 页面切换的效果
    Android 访问本地API doc较慢
    Eclipse插件工具
    Android 性能优化的一些方法
    Android JAVA代码执行shell命令
  • 原文地址:https://www.cnblogs.com/acm1ruoji/p/11045105.html
Copyright © 2011-2022 走看看