点此看题面

大致题意: 给你若干份排序的代码,共\(6\)个子任务,每个子任务让你构造数据使得一份代码用时在给定的\(T\)以内,另一份代码用时超过\(2000000\)。

子任务\(1\):归并排序\(AC\),计数排序\(TLE\)

很简单,要想让计数排序\(TLE\),自然是要让值域尽量大。

由于\(T=7\),因此\(n\)恰好为\(1\),则我们随便选取一个较大的数作为被排序的数即可。

子任务\(2\):冒泡排序\(AC\),选择排序\(TLE\)

这个子任务,我们可以选取一大堆相同的数,然后在里面混进一个不同的数,这样就能过了。

至于数的总数混进数的位置,大概只能靠人肉二分了。

造数据代码如下:

#include<bits/stdc++.h>
#define N 1990//数的总数
#define M 1469//混进数的位置
using namespace std;
int main()
{
freopen("Shion2.out","w",stdout);
register int i;cout<<N<<endl;
for(i=1;i^M;++i) cout<<19<<endl;//输出19(19是我的幸运数字)
cout<<24<<endl;//混进一个24
for(i=1;i<=N-M;++i) cout<<19<<endl;//接着输出19
return 0;
}

子任务\(3\):归并排序\(AC\),快速排序\(TLE\)

经过测试,容易发现归并排序时间复杂度是稳定的。

则通过人肉二分,我们可以求出最大的\(n\)为\(1984\)。

然后就要考虑在这个限制之下如何卡快排。

凭常识可知,快排的时间复杂度是很不稳定的,最坏情况下可以卡到\(O(n^2)\),而这样就足够了。

考虑到在最坏情况下,我们应使中间的数最小(仔细去认真调试一遍快排的代码即可发现),而且每次操作后其实就相当于把最左边的数和中间的数换个位置

所以,我就写了个递归函数模拟快排来求答案。

造数据代码如下:

#include<bits/stdc++.h>
#define N 1984
using namespace std;
int p[N+5],ans[N+5];
void DivideAndSolve(int l,int r,int v)//模拟快排来求答案
{
int x=l+r>>1,i=l,j=x;!ans[p[x]]&&(ans[p[x]]=++v);//使中间的数最小
p[i]^=p[j]^=p[i]^=p[j],++i<r&&(DivideAndSolve(i,r,v),0);//交换最左边的数和中间的数
}
int main()
{
freopen("Shion3.out","w",stdout);
register int i;cout<<N<<endl;for(i=1;i<=N;++i) p[i]=i;//初始化每个位置上是原序列中的第i个数(因为之后会换位置)
for(DivideAndSolve(1,N,0),i=1;i<=N;++i) cout<<ans[i]<<endl;//递归,然后输出答案
return 0;
}

子任务\(4\):计数排序\(AC\),冒泡排序\(TLE\)

卡冒泡排序,需要构造逆序对。我们可以构造出一个序列,使其数字逐个递减。

由于要让计数排序\(AC\)且\(T\)较小,所以值域不能太大。

因此我们可以使每个数重复多次,然后人肉二分数的总数序列中数的最大值(这样可以同时求出每个数字的重复次数),就可以了。

造数据代码如下:

#include<bits/stdc++.h>
#define N 1012//数的总数
#define M 30//序列中数的最大值
using namespace std;
int main()
{
freopen("Shion4.out","w",stdout);
register int i,j;cout<<N<<endl;
for(i=M;i;--i) for(j=1;j<=N/M;++j) cout<<i<<endl;//递减输出每个数,且每个数重复多次
for(j=1;j<=N-(N/M)*M;++j) cout<<0<<endl;//由于不能恰好除尽,因此剩余的个数我们输出0
return 0;
}

子任务\(5\):选择排序\(AC\),冒泡排序\(TLE\)

又是要卡冒泡排序,但这次没有了值域的限制,直接二分递归构造序列即可。

造数据代码如下:

#include<bits/stdc++.h>
#define N 1004
using namespace std;
int ans[N+5];
void DivideAndSolve(int l,int r,int v)//二分构造序列
{
if(l>r) return;//当左边界大于右边界时,退出
int mid=l+r>>1;ans[mid]=v,//给中间的数赋值
DivideAndSolve(l,mid-1,v+r-mid+1),//处理左边
DivideAndSolve(mid+1,r,v+1);//处理右边
}
int main()
{
freopen("Shion5.out","w",stdout);
register int i;cout<<N<<endl;
for(DivideAndSolve(1,N,0),i=1;i<=N;++i) cout<<ans[i]<<endl;//构造,然后输出
return 0;
}

子任务\(6\):\(Bogo\)排序\(AC\),快速排序\(TLE\)

毫无疑问,是本题当中最恶心的一个子任务。

首先,不难想到,这题的随机肯定有某种规律。

于是便想到把这些数字一个个扔进计算器里看其二进制下的值,于是发现\(RNG\_a\)和\(RNG\_b\)着两个参数差不多在模一个不太大的\(2\)的幂的情况下余\(1\)。

所以,它的交换数据这一部分的代码中的\(j\),其实就等于\((seed+i+1)\%n\)。

然后经过一定的测试,可得\(n=4096\)。

由于我们需要在一次之内能够排完序,所以我们倒序处理,就可以构造出原序列。

而我们需要使构造出的序列能卡掉快排,试得\(seed=2048\)。

但是,\(seed\)是要根据\(a_i\)这个序列来算出的,而不是你随便就能定的。

比较容易想到先求出前\(n-1\)个数使\(seed\)得到的值,然后找到一个合适的\(a_n\)使得\(seed\)能够恰好等于\(2048\),但这就需要枚举。

可这个序列的相对大小又不能改变,因此我们枚举范围十分小。

则可以考虑将已经构造出的序列中大于\(a_n\)的数全部加上一个很大的数,这样就能使得相对大小不变。然后再在这一较大的值域中进行枚举,就能找到了。

造数据代码如下:

#include<bits/stdc++.h>
#define N 4096
#define uint unsigned int
#define swap(x,y) (x^=y^=x^=y)
using namespace std;
int a[N+5];
int main()
{
freopen("Shion6.out","w",stdout);
register int i;register uint seed;
for(i=1;i<=N;++i) a[i]=i;for(i=N;i;--i) swap(a[i],a[(i+2048)%N+1]);//倒序处理,构造出原数列
for(i=1;i<=N;++i) a[i]>a[N]&&(a[i]+=1000000);//将已经构造出的序列中大于a[n]的数全部加上一个很大的数,这样就能使得相对大小不变
for(seed=2166136261,i=1;i^N;++i) seed=(seed*16777619)^a[i];//求出前n-1个数使seed得到的值
for(i=4092;i<=1004093;++i) if(((seed*16777619)^i)%N==2048) {a[N]=i;break;}//枚举一个合适的a[n]使得seed能够恰好等于2048
for(cout<<N<<endl,i=1;i<=N;++i) cout<<a[i]<<endl;//输出答案
return 0;
}

附录:答案

以上就是这道题的全部解题思路了。

点击下载答案

【UOJ83】【UR #7】水题出题人(提交答案题)的更多相关文章

  1. 牛客练习赛38 D 题 出题人的手环 (离散化+树状数组求逆序对+前缀和)

    链接:https://ac.nowcoder.com/acm/contest/358/D来源:牛客网 出题人的手环 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K,其他 ...

  2. UOJ#73. 【WC2015】未来程序 提交答案题

    原文链接www.cnblogs.com/zhouzhendong/p/UOJ73.html 前言 纯属理性愉悦. 题解 Subtask1 发现就是求 $a \times b \mod c $ . 写个 ...

  3. uoj #190. 【集训队互测2016】消失的源代码 提交答案题

    Test 1: 发现是一个字母表的映射 把 \('a' \to 'z'\) 打进去找出映射就好了QAQ . Test 2: 求助 \(dalao\) 得知的点.. 答案是 : \(2016x^2 + ...

  4. [UOJ#404][CTSC2018]组合数问题(79分,提交答案题,模拟退火+匈牙利+DP)

    1.4.5.6.10都是op=1的点,除4外直接通过模拟退火调参可以全部通过. #include<cmath> #include<ctime> #include<cstd ...

  5. 一道超级坑爹的水题(ACdream oj 无耻的出题人)

     A - 无耻的出题人 Time Limit: 2000/1000 MS (Java/Others)      Memory Limit: 65536/32768 KB (Java/Others) ...

  6. [BZOJ3203] [SDOI2013]保护出题人(二分+凸包)

    [BZOJ3203] [SDOI2013]保护出题人(二分+凸包) 题面 题面较长,略 分析 对于第i关,我们算出能够打死前k个个僵尸的最小能力值,再取最大值就可以得到\(y_i\). 前j-1个僵尸 ...

  7. 浅谈OI中的提交答案

    在OI中,题目有三类: 传统题 交互题 提交答案题 今天来了解一下第三类 概述 传统题:给你一个题面,你需要交一个程序,评测姬会用你的程序运行你看不到的一些测试点,用输出和正确答案比较 提交答案题:给 ...

  8. 出题人的RP值(牛客练习赛38--A题)(排序)

    链接:https://ac.nowcoder.com/acm/contest/358/A来源:牛客网 题目描述 众所周知,每个人都有自己的rp值(是个非负实数),膜别人可以从别人身上吸取rp值. 然而 ...

  9. 出题人的女装(牛客练习赛38题B) (概率+分式运算)

    链接:https://ac.nowcoder.com/acm/contest/358/B来源:牛客网 出题人的女装 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K,其他 ...

随机推荐

  1. Linux字符设备简单示例

    1. Linux字符设备是一种按字节来访问的设备,字符驱动则负责驱动字符设备,这样的驱动通常实现open.close.read和write系统调用.例如:串口.Led.按键等. 2. 通过字符设备文件 ...

  2. @AutoConfigureAfter不生效 @Configration bean的创建顺序

    https://gooroo.io/GoorooTHINK/Article/17466/Lessons-Learned-Writing-Spring-Boot-Auto-Configurations/ ...

  3. OpenCV属性页配置问题~

    详细的OpenCV属性页的安装流程,参考这个网站:http://m.bubuko.com/infodetail-793518.html 运行例子时候,如果遇到这个问题,可能配置环境时候出现问题了. 此 ...

  4. mc03_IntelliJ IDEA配置github

    配置本地git仓库 首先配置一个本地的git仓库,熟悉一下git上传文件到github的过程,具体操作参考 mc02_配置本地git仓库并上传到github IntelliJ IDEA与github的 ...

  5. java——平衡二叉树 AVLTree、AVLMap、AVLSet

    平衡二叉树:对于任意一个节点,左子树和右子树的高度差不能超过1 package Date_pacage; import java.util.ArrayList; public class AVLTre ...

  6. Spring---数据缓存(未完待续)

    1.为什么需要数据缓存? 程序的瓶颈大都在数据库,而内存的速度是远远大于硬盘的,当我们需要重复读取相同数据时,一次又一次的请求数据库或者远程服务,导致大量的时间浪费在数据库或者 远程服务上,导致程序性 ...

  7. 提高Service提高进程优先级别,不被系统容易杀死

    1.首先要了解lowmemroykiller机制  在Android的lowmemroykiller机制中,会对于所有进程进行分类,对于每一类别的进程会有其oom_adj值的取值范围,oom_adj值 ...

  8. linux 测试远程主机端口

    检测远程端口是否打开 常用telnet 110.101.101.101 80方式测试远程主机端口是否打开. 除此之外还可以使用: 方法1.nmap ip -p port 测试端口 nmap ip 显示 ...

  9. Unity Screen Screen.SetResolution 设置分辨率

    Screen.SetResolution 设置分辨率 C# => public static void SetResolution(int width, int height, bool ful ...

  10. UGUI RectTransform 矩形变换

    UGUI游戏对象基本都有这个组件. float radius; radius = GetComponent<RectTransform>().sizeDelta.x; radius = ( ...