zoukankan      html  css  js  c++  java
  • LuoguP2765 魔术球问题(最大流)

    题目描述

    «问题描述:

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

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

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

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

    «编程任务:

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

    输入输出格式

    输入格式:

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

    输出格式:

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

    解题思路:

    假如说告诉你多少球,需要多少柱子是显然可求的。

    那和这道题就一样了。

    发现球多柱子自然多,因为球只能一个一个摞,

    所以没添加一个球只能放在没添加时的合法方案上的,

    所以柱子数单增。

    不要二分答案,那样还要拆图,枚举就好了。

    注意要记录方案。

    代码:

      1 #include<cmath>
      2 #include<cstdio>
      3 #include<vector>
      4 #include<cstring>
      5 #include<algorithm>
      6 const int oo=0x3f3f3f3f;
      7 namespace stb{
      8     template<class tnt>
      9     class queue{
     10         #define INF 1000000
     11         public:
     12             queue(){h=1,t=0;}
     13             int nxt(int x){if(x+1==INF)return 1;return x+1;}
     14             bool empty(void){return nxt(t)==h;}
     15             void push(tnt x){t=nxt(t);l[t]=x;}
     16             tnt front(void){return l[h];}
     17             void clear(void){h=1;t=0;}
     18             void pop(void){h=nxt(h);}
     19         private:
     20             tnt l[INF];
     21             int h,t;
     22         #undef INF
     23     };
     24 };
     25 struct pnt{
     26     int hd;
     27     int lyr;
     28     int nxt;
     29     int now;
     30     bool nos;
     31 }p[100000];
     32 struct ent{
     33     int twd;
     34     int lst;
     35     int vls;
     36 }e[1000000];
     37 int cnt;
     38 int n,m;
     39 int S,T;
     40 int top;
     41 stb::queue<int>Q;
     42 std::vector<int>Ans[600];
     43 void ade(int f,int t,int v)
     44 {
     45     cnt++;
     46     e[cnt].twd=t;
     47     e[cnt].vls=v;
     48     e[cnt].lst=p[f].hd;
     49     p[f].hd=cnt;
     50     return ;
     51 }
     52 bool Bfs(void)
     53 {
     54     Q.clear();
     55     for(int i=0;i<=(m<<1|1);i++)
     56         p[i].lyr=0;
     57     p[S].lyr=1;
     58     Q.push(S);
     59     while(!Q.empty())
     60     {
     61         int x=Q.front();
     62         Q.pop();
     63         for(int i=p[x].hd;i;i=e[i].lst)
     64         {
     65             int to=e[i].twd;
     66             if(p[to].lyr==0&&e[i].vls>0)
     67             {
     68                 p[to].lyr=p[x].lyr+1;
     69                 if(to==T)
     70                     return true;
     71                 Q.push(to);
     72             }
     73         }
     74     }
     75     return false;
     76 }
     77 int Dfs(int x,int fll)
     78 {
     79     if(x==T)
     80         return fll;
     81     for(int& i=p[x].now;i;i=e[i].lst)
     82     {
     83         int to=e[i].twd;
     84         if(p[to].lyr==p[x].lyr+1&&e[i].vls>0)
     85         {
     86             int ans=Dfs(to,std::min(fll,e[i].vls));
     87             if(ans>0)
     88             {
     89                 e[i].vls-=ans;
     90                 e[((i-1)^1)+1].vls+=ans;
     91                 p[x].nxt=to;
     92                 if(S!=x)
     93                     p[to-1].nos=true;
     94                 return ans;
     95             }
     96         }
     97     }
     98     return 0;
     99 }
    100 int Dinic(void)
    101 {
    102     int ans=0;
    103     while(Bfs())
    104     {
    105         for(int i=0;i<=(m<<1|1);i++)
    106             p[i].now=p[i].hd;
    107         int dlt;
    108         while(dlt=Dfs(S,oo))
    109             ans+=dlt;
    110     }
    111     return ans;
    112 }
    113 int main()
    114 {
    115     int bulp=0;
    116     scanf("%d",&n);
    117     S=0,T=1;m=1;
    118     for(int i=1;;i++)
    119     {
    120         m++;
    121         ade(S,i<<1,1);
    122         ade(i<<1,S,0);
    123         ade(i<<1|1,T,1);
    124         ade(T,i<<1|1,0);
    125         for(int j=sqrt(i);j*j-i<i;j++)
    126         {
    127             if(j*j-i<=0)
    128                 continue;
    129             ade((j*j-i)<<1,i<<1|1,1);
    130             ade(i<<1|1,(j*j-i)<<1,0);
    131         }
    132         bulp+=1-Dinic();
    133         if(bulp==n+1)
    134         {
    135             printf("%d
    ",i-1);
    136             break;
    137         }
    138         for(int j=1;j<=top;j++)
    139             Ans[j].clear();
    140         top=0;
    141         for(int j=1;j<=i;j++)
    142         {
    143             if(!p[j<<1].nos)
    144             {
    145                 top++;
    146                 for(int k=j<<1;k!=S&&k>0;k=p[k].nxt-1)
    147                     Ans[top].push_back(k>>1);
    148             }
    149         }
    150     }
    151     for(int i=1;i<=top;i++)
    152     {
    153         for(int j=0;j<Ans[i].size();j++)
    154             printf("%d ",Ans[i][j]);
    155         printf("
    ");
    156     }
    157     return 0;
    158 }
  • 相关阅读:
    Java进阶之内部类
    Java进阶之集合框架
    Java进阶之异常
    Java进阶之JVM虚拟机(Java Virtual Machine)
    Java进阶之String类
    Java进阶之Nnumber类和Math
    Java基础之流程控制语句
    Java基础之标识符与修饰符
    Java基础之数据类型与运算符
    数据库事务与事务隔离级别
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10205277.html
Copyright © 2011-2022 走看看