AC日记——魔术球问题 洛谷 P2765
题目描述
«问题描述:
假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为1,2,3,...的球。
(1)每次只能在某根柱子的最上面放球。
(2)在同一根柱子中,任何2个相邻球的编号之和为完全平方数。
试设计一个算法,计算出在n根柱子上最多能放多少个球。例如,在4 根柱子上最多可放11 个球。
«编程任务:
对于给定的n,计算在n根柱子上最多能放多少个球。
输入输出格式
输入格式:
第1 行有1个正整数n,表示柱子数。
输出格式:
程序运行结束时,将n 根柱子上最多能放的球数以及相应的放置方案输出。文件的第一行是球数。接下来的n行,每行是一根柱子上的球的编号。
输入输出样例
4
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[]; int if_z,n,mid,l,r,cnt,head[maxn],ans;
int s=,t=maxn-,deep[maxn],next[maxn]; bool if_[maxn]; char Cget; inline void in(int &now)
{
now=,if_z=,Cget=getchar();
while(Cget>''||Cget<'')
{
if(Cget=='-') if_z=-;
Cget=getchar();
}
while(Cget>=''&&Cget<='')
{
now=now*+Cget-'';
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=,head[v]=cnt;
} bool BFS()
{
memset(deep,-,sizeof(deep));
queue<int>que;que.push(s);deep[s]=;
while(!que.empty())
{
int pos=que.front();que.pop();
for(int i=head[pos];i;i=edge[i].next)
{
if(edge[i].flow>&&deep[edge[i].to]<)
{
deep[edge[i].to]=deep[pos]+;
if(edge[i].to==t) return true;
que.push(edge[i].to);
}
}
}
return false;
} int flowing(int now,int flow)
{
if(flow==||now==t) return flow;
int oldflow=;
for(int i=head[now];i;i=edge[i].next)
{
if(deep[edge[i].to]!=deep[now]+||edge[i].flow==) 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^].flow+=pos;
if(flow==) return oldflow;
}
return oldflow;
} bool check()
{
cnt=;
memset(next,,sizeof(next));
memset(head,,sizeof(head));
memset(if_,false,sizeof(if_));
for(int i=;i<=mid;i++)
{
for(int j=i+;j<=mid;j++)
{
int tmp=sqrt(i+j);
if(tmp*tmp==i+j) edge_add(i,j+mid,);
}
}
for(int i=;i<=mid;i++)
{
edge_add(s,i,);
edge_add(i+mid,t,);
}
int pos=mid;
while(BFS()) pos-=flowing(s,0x7ffffff);
if(pos>n) return true;
else return false;
} int main()
{
in(n);
l=,r=;
while(l<=r)
{
mid=(l+r)>>;
if(check()) ans=mid,r=mid-;
else l=mid+;
}
mid=ans-;
check();
printf("%d\n",mid);
for(int i=;i<mid;i++)
{
if(if_[i]) continue;
printf("%d",i);
int pos=i;
while(next[pos])
{
printf(" %d",next[pos]);
pos=next[pos];
}
printf("\n");
}
return ;
}
AC日记——魔术球问题 洛谷 P2765的更多相关文章
- AC日记——[SDOI2015]星际战争 洛谷 P3324
题目描述 3333年,在银河系的某星球上,X军团和Y军团正在激烈地作战. 在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进攻X军团的阵地,其中第i个巨型机器人的装甲值为Ai.当一个巨型机器人的装甲值 ...
- AC日记——联合权值 洛谷 P1351
题目描述 无向连通图G 有n 个点,n - 1 条边.点从1 到n 依次编号,编号为 i 的点的权值为W i ,每条边的长度均为1 .图上两点( u , v ) 的距离定义为u 点到v 点的最短距离. ...
- AC日记——I Hate It 洛谷 P1531
题目背景 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少.这让很多学生很反感. 题目描述 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的 ...
- AC日记——神奇的幻方 洛谷 P2615(大模拟)
题目描述 幻方是一种很神奇的N*N矩阵:它由数字1,2,3,……,N*N构成,且每行.每列及两条对角线上的数字之和都相同. 当N为奇数时,我们可以通过以下方法构建一个幻方: 首先将1写在第一行的中间. ...
- AC日记——[CQOI2009]DANCE跳舞 洛谷 P3153
[CQOI2009]DANCE跳舞 思路: 二分+最大流: 代码: #include <cstdio> #include <cstring> #include <iost ...
- AC日记——松江1843路 洛谷七月月赛
松江1843路 思路: 三分: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 100005 #define ...
- AC日记——严酷的训练 洛谷 P2430
严酷的训练 思路: 背包: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 5005 int n,m,bi[m ...
- AC日记——[SDOI2010]大陆争霸 洛谷 P3690
[SDOI2010]大陆争霸 思路: dijkstra模板: 代码: #include <bits/stdc++.h> using namespace std; #define maxn ...
- AC日记——小魔女帕琪 洛谷 P3802
小魔女帕琪 思路: 概率公式计算: 代码: #include <bits/stdc++.h> using namespace std; ],sig; int main() { ;i< ...
随机推荐
- Unity基础-Input接口
input 底层的设备输入接口,在开发中很少用到 Input.GetKey() // Update is called once per frame void Update () { if (Inpu ...
- Python爬虫系列-Requests库详解
Requests基于urllib,比urllib更加方便,可以节约我们大量的工作,完全满足HTTP测试需求. 实例引入 import requests response = requests.get( ...
- Linux中让alias设置永久生效的方法详解
Linux中让alias设置永久生效的方法详解 一.问题描述 1.有很多时候我们想要将很多操作作为一个步骤,那么在不作为系统的服务的情况下,别名是我们最好的选择,但是发现别名只能在一次会话中生效,重启 ...
- Hard problem CodeForces - 706C
Time limit1000 ms Memory limit262144 kB 题目: Vasiliy is fond of solving different tasks. Today he fou ...
- socket中send和recv函数
Socket一次Recv接受的字节有限制么? 从套接字接收数据. 返回值是表示接收数据的字符串. 一次接收的最大数据量由bufsize指定.它默认为零. 注意为了最好地匹配硬件和网络现实,bufsiz ...
- c++ dll 创建
建立一个C++的Win32DLL,这里要注意选择"Export symbols"导出符号.点击完成. 如下图所示: 由于项目的名称是"TestCPPDLL" ...
- vim 查找替换命令
http://vim.wikia.com/wiki/Search_and_replace
- Python文件处理、函数的基本应用
可读可写: r+t:可读.可写 w+t:可写.可读with open('b.txt','w+t',encoding='utf-8') as f: print(f.readable()) p ...
- [python篇][1]configparser 问题汇总
https://wiki.python.org/moin/ConfigParserExamples 1 错误一 nicodeEncodeError: 'ascii' codec can't encod ...
- springboot添加外部jar包及打包
项目中除了从pom中添加依赖包,还可以添加本地的jar包,怎么做呢? 1.在src下新建目录lib,将jar包添加到lib中 2.在pom文件里添加配置以下属性,就可以使用jar包了 <depe ...