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");
    }
}




目录
相关文章
|
7月前
ZZULIOJ----2618: ACM-ICPC亚洲区域赛ZZUL
ZZULIOJ----2618: ACM-ICPC亚洲区域赛ZZUL
upc2021秋组队训练赛第一场 ICPC North Central NA Contest 2020
upc2021秋组队训练赛第一场 ICPC North Central NA Contest 2020
95 0
upc2021秋组队训练赛第一场 ICPC North Central NA Contest 2020
ICPC North Central NA Contest 2018 C . Rational Ratio(结论 模拟 gcd)
ICPC North Central NA Contest 2018 C . Rational Ratio(结论 模拟 gcd)
115 0
HDOJ/HDU 1022 Train Problem I(模拟栈)
HDOJ/HDU 1022 Train Problem I(模拟栈)
125 0
HDOJ/HDU 1022 Train Problem I(模拟栈)
HDOJ/HDU 1328 IBM Minus One(水题一个,试试手)
HDOJ/HDU 1328 IBM Minus One(水题一个,试试手)
106 0
|
机器学习/深度学习
HDOJ 2081 手机短号
HDOJ 2081 手机短号
104 0
HDOJ 1393 Weird Clock(明白题意就简单了)
HDOJ 1393 Weird Clock(明白题意就简单了)
115 0
HDOJ(HDU) 2061 Treasure the new start, freshmen!(水题、)
HDOJ(HDU) 2061 Treasure the new start, freshmen!(水题、)
137 0
|
人工智能 算法
爆表!猜猜这个大会的IQ总值有多高?
零售、工业、金融、城市、航空、自动驾驶…… 世界远比我们想象的更复杂,也正走向我们希望的简单。
3216 0