zoj 长沙 Bizarre Routine 模拟

简介:

     题目给了个快排程序,要求构造序列使比较次数等于except。

     于是给定n,我们可以求出可以到达的最小比较次数,和最大比较次数,n*(n-1)/2

     根据快排,每次划分,左边是比其小的数,右边是大的。因此如果划分序列,只需让ans[m]=m;即可划分为m-l-1和r-mid两个,比赛的时候就这里没想清楚。

     而最小值和(Min[x]+Min[len-x])最大值和都是单调递减的,二分即可

    最后再交换两次,回到k位置即可

    其实整个过程就是模拟下快排的逆过程

/*
author:jxy
lang:C/C++
university:China,Xidian University
**If you need to reprint,please indicate the source**
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
int Low[10005];
int A,B;
int ans[10005];
int Mi(int n)//确定下界
{
    if(n<=1)return 0;
    if(~Low[n])return Low[n];
    return Low[n]=Mi(n/2)+Mi(n-1-n/2)+n-1;
}
void solve(int l,int r,int e)
{
    if(l>r)return;
    if(l==r)
    {
        ans[l]=l;
        return;
    }
    int len=r-l;
    int ll=0,rr=(len+1)>>1,mid;
    e-=len;
    while(ll<rr)//二分查找划分长度
    {
        mid=(ll+rr)>>1;
        if(Mi(mid)+Mi(len-mid)>e)ll=mid+1;
        else rr=mid;
    }
    mid=ll+l;
    solve(l,mid-1,Mi(ll));
    solve(mid+1,r,e-Mi(ll));
    ans[mid]=mid;
    swap(ans[mid],ans[r]);
    swap(ans[r],ans[(A*l+B*r)/(A+B)]);//返回标兵
}
int main()
{
    int n,e;
    memset(Low,-1,sizeof(Low));
    while(~scanf("%d%d%d%d",&n,&e,&A,&B))
    {
        if(Mi(n)>e||n*(n-1)/2<e) puts("NOWAY");
        else
        {
            solve(1,n,e);
            for(int i=1;i<=n;i++)
            {
                if(i>1)putchar(' ');
                printf("%d",ans[i]);
            }
            puts("");
        }
    }
}


这边是测试程序

#include <cstdio>
#include<iostream>
#include <algorithm>
using namespace std;
int T,A,B;
bool less_than(int x, int y) {
	T++;
	return x < y;
}
void work(int array[], int l, int r) {
	if (l >= r) return;
	swap(array[(l * A + r * B) / (A + B)], array[r]);
	int index = l;
	for (int 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 - 1);
	work(array, index + 1, r);
}
int array[100000];

int main() {
    int n,expect;
	while(~scanf("%d%d%d%d",&n,&expect,&A,&B))
    {
        T=0;
        for(int i=0;i<n;i++)
            scanf("%d",&array[i]);
        work(array, 0, n - 1);
        if (T == expect)
            puts("YES");
        else
            puts("NO");
    }
}




目录
相关文章
|
Cloud Native Dubbo 应用服务中间件
阿里巴巴捐献的14个顶级开源项目,国内开源贡献第一!
代表性的项目包括龙蜥操作系统、Apache RocketMQ、Apache Dubbo、Spring Cloud Alibaba 等
|
存储 缓存 负载均衡
【2022持续更新】大数据最全知识点整理-HBase篇
【2022持续更新】大数据最全知识点整理-HBase篇
1444 0
【2022持续更新】大数据最全知识点整理-HBase篇
|
11月前
|
机器学习/深度学习 存储 数据采集
大数据性能优化
【10月更文挑战第24天】
575 3
|
7月前
|
监控 数据挖掘 API
🔥 新手也能懂!Shopee商品详情API接口全攻略
本文介绍了一个用于采集Shopee商品数据的API及其使用方法。通过该API,电商运营者可快速监控竞品价格、销量与评价;数据分析人员能批量获取商品信息进行市场调研;开发者则可构建自动化工具如比价系统或生成报告。内容涵盖注册准备、关键参数说明、Python代码示例以及实战案例(如监控竞品差评)。此外,还提供了防封技巧、常见问题解答及适合人群分析,帮助用户高效上手并解决实际需求。
|
图形学
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版6(附带项目源码)
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版6(附带项目源码)
340 1
|
SQL Java 数据库连接
SQL DISTINCT关键字详解
SQL DISTINCT关键字详解
|
缓存 关系型数据库 MySQL
涉及到Linux系统的软件包依赖和冲突问题
涉及到Linux系统的软件包依赖和冲突问题
598 1
|
负载均衡 安全 网络协议
什么是流量攻击? 流量攻击怎么处理?
什么是流量攻击? 流量攻击怎么处理?
|
SQL Java 数据库连接
Mybatis的动态SQL分页及特殊字符的使用
Mybatis的动态SQL分页及特殊字符的使用
134 0
|
Dart Unix Linux
Flutter:path 库详解
本文主要介绍一下 path 库的使用。
1015 0