题目意思:

  给定n, expect, a, b 要求你构造一组array[],存放一个1..n的排列,使的下面的程序能输出YES

  题目所示代码:

    

 bool less_than(x, y) {
T++;
return x < y;
}
void work(array[], l, r) {
if (l >= r) return;
swap(array[(l * A + r * B) / (A + B)], array[r]);
int index = l;
for (i = l; i < r; i++)
if (less_than(array[i], array[r]))
swap(array[index++], array[i]);
swap(array[r], array[index]);
work(array, l, index - );
work(array, index + , r);
}
void main() {
T = ;
Input(n, expect, A, B, array[]);
work(array, , n - );
if (T == expect)
Output("YES");
else
Output("NO");
}

sort

  壕无疑问这是一个快排!

n个数排列,T的上限是sigma(1..n-1) = n*(n-1)/2

而下限则可以通过递推得到

  mi[x] = 0                        for x =0, 1

  mi[x] = x-1 + min(mi[i] + mi[x-i-1])  (0 <=i < x)    for x > 1

当然根据经验得到,i应该是取x/2的时候最好,跑了一下,mi数组也确实没变。。当然跑n^2的应该时间也够。

而且实际上 mi[i] + mi[x-i-1] 在i = 0..x/2呈现非递增的性质,解法用到了这个性质。

当expext在上下限之间的时候,可以通过递归构造

void work(int l, int r, int c)

构造区间[l,r] 使得这个区间的T = c

显然这个区间要消耗r - l次

设对这个区间的第一次排序后中间数在m位置,还要消耗区间[l,m - 1], [m+1, r]

当m = l .. (l+r)/2   (Ps: 当 m > (l+r)/2时 和<= (l+r)/2的情况是等价的)

假如[l,m - 1], [m+1, r]均取最小值,则数值呈现非递减

假如[l,m - 1], [m+1, r]均取最大值,则数值呈现非递减

由于这个区间一定存在m符合条件,那么取第一个使得区间消耗最小值mi(l,m - 1) + mi(m+1, r) <= c - (r-l) 的必然符合要求(Ps: 把最小值和最大值在纸上画一下函数就明了)

让左区间取消耗最小值, 然后递归构造

work(l,m-1,mi[l-m]) work(m1,r,c - (r-l) - mi[l-m])

我们希望区间[l, r]第一次sort后,p[l..r] = [ p[l..m-1], m ,p[m+1..r] ]

那么,通过给定的a, b计算得到m原本的下标,手动回滚他程序中的两次swap。

构造完毕,代码如下:

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = ;
int a,b,p[N];
int mi[N];
inline bool can(int l,int r,int c){
int n = r-l+;
return c>=mi[n] && c<=n*(n-)/;
}
inline void mysort(int l,int m,int r,int id){
p[m] = m;
swap(p[m],p[r]);
swap(p[r],p[id]);
}
void work(int l,int r,int c){
if(l>r) return;
if(l == r){
p[l] = l;
return;
}
int lt = l,rt = (l+r)/+, m;
c -= r-l;
while(lt<rt){
m = (lt + rt)>>;
if(mi[m-l]+mi[r-m] > c) lt = m + ;
else rt = m;
}
m = lt;
work(l,m-,mi[m-l]);
work(m+,r,c-mi[m-l]);
mysort(l,m,r,(l*a + r*b)/(a+b));
}
int n,m;
int main(){
//freopen("in.txt", "r", stdin);
for(int i=;i<N;i++){
int x = i/, y = i-x-;
mi[i] = mi[x]+mi[y]+i-;
}
//for(int i=0;i<=20;i++)cout<<i<<" "<<mi[i]<<endl;
while(~scanf("%d%d%d%d",&n,&m,&a,&b)){
if(!can(,n-,m)){
puts("NOWAY");
continue;
}
work(,n-,m);
for(int i=;i<n;i++) printf(i==n-?"%d\n":"%d ",p[i]+);
}
return ;
}

ZOJ Bizarre Routine 2013杭州网赛B题的更多相关文章

  1. HDU 4746 HDOJ Mophues 2013杭州网赛I题

    比赛的时候就预感到这题能出,但是会耗时比较多.结果最后是出了,但是有更简单的题没出. 是不是错误的决策呢?谁知道呢 题目意思: 定义f(x) = x分解质因数出来的因子个数 如 x = p0 * p0 ...

  2. HDU 4747 Mex (2013杭州网络赛1010题,线段树)

    Mex Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submis ...

  3. HDU 4741 Save Labman No.004 (2013杭州网络赛1004题,求三维空间异面直线的距离及最近点)

    Save Labman No.004 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  4. HDU 4739 Zhuge Liang's Mines (2013杭州网络赛1002题)

    Zhuge Liang's Mines Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  5. HDU 4738 Caocao's Bridges (2013杭州网络赛1001题,连通图,求桥)

    Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  6. 2013杭州现场赛B题-Rabbit Kingdom

    杭州现场赛的题.BFS+DFS #include <iostream> #include<cstdio> #include<cstring> #define inf ...

  7. 2013杭州网赛 1001 hdu 4738 Caocao's Bridges(双连通分量割边/桥)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4738 题意:有n座岛和m条桥,每条桥上有w个兵守着,现在要派不少于守桥的士兵数的人去炸桥,只能炸一条桥 ...

  8. 2013杭州网络赛D题HDU 4741(计算几何 解三元一次方程组)

    Save Labman No.004 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  9. 2013杭州网络赛C题HDU 4640(模拟)

    The Donkey of Gui Zhou Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/O ...

随机推荐

  1. dicom和dicomdir

    转载http://blog.sina.com.cn/s/blog_4bce5f4b01019ix5.html DICOM 文件内容在 Part 3 DICOM IOD 里定义.CT, MR, CR, ...

  2. linux下Tomcat配置提示权限不够解决办法

    在终端输入命令 sudo chmod -R 777 /opt/Tomcat,那么Tomcat文件夹和它下面的所有子文件夹的属性都变成了777(读/写/执行权限)

  3. JAVAOOP1

    封装属性:alt+shift+s------r------alt+a-----回车 创建无参构造和带参构造:alt+shift+s----点击鼠标选择 格式化代码:ctrl+shift+f 成员变量系 ...

  4. Windows下如何安装composer

    相对 来说并不难直接将此文件下载安装即可 1 https://getcomposer.org/Composer-Setup.exe 文件地址由官方提供 https://getcomposer.org/ ...

  5. PLC状态机编程-如何在STL中使用状态机

    搞PLC编程多年,一直不知道状态机,学习matlab后,发现状态机编程异常方便,过去很多编程时的疑惑豁然开朗起来.今天跟大家分享一下如何在STL中使用状态机. 下面是用状态机描述的控制任务. 这个状态 ...

  6. Android Studio的Log日志调试

    本人菜鸟一枚,极大发挥了搜索的功能.现记录一番,以备后患. 用断点真的很烦,因为之前写linux的时候,就是用最蠢但是也是挺有帮助的printf()来进行调试. 其实用Log输出日志的原理也是差不多的 ...

  7. 从库函数操作RCC的流程来理解偏移变量

    下面是库函数操作RCC流程,看完后有我的疑问:偏移地址的理解 1,库函数直接操作:RCC库函数操作  RCC_APB2PeriphClockCmd ()RCC->APB2ENR |= RCC_A ...

  8. 3 Mongodb数据查询1

    1.基本查询 方法find():查询 db.集合名称.find({条件文档}) 方法findOne():查询,只返回第一个 db.集合名称.findOne({条件文档}) 方法pretty():将结果 ...

  9. Trident整合MongoDB

    MongoDB是大数据技术中常用的NoSql型数据库,它提供的大量的查询.聚合等操作函数,对于大量查询的日志系统来说,该MongoDB是大数据日志存储的福音.Storm的高级编程技术Trident,也 ...

  10. 什么是App加壳,以及App加壳的利与弊

    非著名程序员涩郎 非著名程序员,字耿左直右,号涩郎,爱搞机,爱编程,是爬行在移动互联网中的一名码匠!个人微信号:loonggg,微博:涩郎,专注于移动互联网的开发和研究,本号致力于分享IT技术和程序猿 ...