• AC日记——魔术球问题 洛谷 P2765


    题目描述

    «问题描述:

    假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为1,2,3,...的球。

    (1)每次只能在某根柱子的最上面放球。

    (2)在同一根柱子中,任何2个相邻球的编号之和为完全平方数。

    试设计一个算法,计算出在n根柱子上最多能放多少个球。例如,在4 根柱子上最多可放11 个球。

    «编程任务:

    对于给定的n,计算在n根柱子上最多能放多少个球。

    输入输出格式

    输入格式:

    第1 行有1个正整数n,表示柱子数。

    输出格式:

    程序运行结束时,将n 根柱子上最多能放的球数以及相应的放置方案输出。文件的第一行是球数。接下来的n行,每行是一根柱子上的球的编号。

    输入输出样例

    输入样例#1:
    4
    输出样例#1:
    11
    1 8
    2 7 9
    3 6 10
    4 5 11

    说明

    感谢 @PhoenixEclipse 提供spj

    思路:

      因为有数据范围,我们采取二分答案(枚举);

      然后,走最大流,当当前球数减去最大流数==n+1时,当前球数-1就是答案;

    来,上代码:

    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    #define maxn 4000
    
    using namespace std;
    
    struct EdgeType {
        int to,next,flow;
    };
    struct EdgeType edge[3000005];
    
    int if_z,n,mid,l,r,cnt,head[maxn],ans;
    int s=0,t=maxn-1,deep[maxn],next[maxn];
    
    bool if_[maxn];
    
    char Cget;
    
    inline void in(int &now)
    {
        now=0,if_z=1,Cget=getchar();
        while(Cget>'9'||Cget<'0')
        {
            if(Cget=='-') if_z=-1;
            Cget=getchar();
        }
        while(Cget>='0'&&Cget<='9')
        {
            now=now*10+Cget-'0';
            Cget=getchar();
        }
        now*=if_z;
    }
    
    inline void edge_add(int u,int v,int w)
    {
        edge[++cnt].to=v,edge[cnt].next=head[u],edge[cnt].flow=w,head[u]=cnt;
        edge[++cnt].to=u,edge[cnt].next=head[v],edge[cnt].flow=0,head[v]=cnt;
    }
    
    bool BFS()
    {
        memset(deep,-1,sizeof(deep));
        queue<int>que;que.push(s);deep[s]=0;
        while(!que.empty())
        {
            int pos=que.front();que.pop();
            for(int i=head[pos];i;i=edge[i].next)
            {
                if(edge[i].flow>0&&deep[edge[i].to]<0)
                {
                    deep[edge[i].to]=deep[pos]+1;
                    if(edge[i].to==t) return true;
                    que.push(edge[i].to);
                }
            }
        }
        return false;
    }
    
    int flowing(int now,int flow)
    {
        if(flow==0||now==t) return flow;
        int oldflow=0;
        for(int i=head[now];i;i=edge[i].next)
        {
            if(deep[edge[i].to]!=deep[now]+1||edge[i].flow==0) continue;
            int pos=flowing(edge[i].to,min(flow,edge[i].flow));
            if(edge[i].to>mid)
            {
                next[now]=edge[i].to-mid;
                if_[next[now]]=true;
            }
            flow-=pos;
            oldflow+=pos;
            edge[i].flow-=pos;
            edge[i^1].flow+=pos;
            if(flow==0) return oldflow;
        }
        return oldflow;
    }
    
    bool check()
    {
        cnt=1;
        memset(next,0,sizeof(next));
        memset(head,0,sizeof(head));
        memset(if_,false,sizeof(if_));
        for(int i=1;i<=mid;i++)
        {
            for(int j=i+1;j<=mid;j++)
            {
                int tmp=sqrt(i+j);
                if(tmp*tmp==i+j) edge_add(i,j+mid,1);
            }
        }
        for(int i=1;i<=mid;i++)
        {
            edge_add(s,i,1);
            edge_add(i+mid,t,1);
        }
        int pos=mid;
        while(BFS()) pos-=flowing(s,0x7ffffff);
        if(pos>n) return true;
        else return false;
    }
    
    int main()
    {
        in(n);
        l=1,r=1600;
        while(l<=r)
        {
            mid=(l+r)>>1;
            if(check()) ans=mid,r=mid-1;
            else l=mid+1;
        }
        mid=ans-1;
        check();
        printf("%d
    ",mid);
        for(int i=1;i<mid;i++)
        {
            if(if_[i]) continue;
            printf("%d",i);
            int pos=i;
            while(next[pos])
            {
                printf(" %d",next[pos]);
                pos=next[pos];
            }
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    Discuz X 2.5 点点(伪静态)
    jq 、xml 省市级联动
    php memcache 初级使用(2)
    关于windows虚拟内存管理的页目录自映射
    SharePoint 2010 网络上的开发经验和资源
    SharePoint 2010 Reporting Services 报表服务器正在内置 NT AUTHORITY\SYSTEM 账户下运行 解决方法
    SharePoint 2010 Reporting Services 报表服务器无法解密用于访问报表服务器数据库中的敏感数据或加密数据的对称密钥 解决方法
    Active Directory Rights Management Services (AD RMS)无法检索证书层次结构。 解决方法
    SharePoint 2010 Reporting Services 报表服务器实例没有正确配置 解决方法
    SharePoint 2010 页面引用 Reporting Services 展现 List 报表
  • 原文地址:https://www.cnblogs.com/IUUUUUUUskyyy/p/6444685.html
Copyright © 2020-2023  润新知