Ural 1082|Gaby Ivanushka|数学推导|快速排序|程序分析

http://acm.timus.ru/problem.aspx?space=1&num=1082

题目大意

给定以下程序

 #include <stdio.h>  
 long c;
 long A[N];

 long P(long l, long r)
 {
  long x=A[l],
       i=l-1,
       j=r+1,
       t;
  while(1)
  {
   do{--j; ++c;}
   while(A[j]>x);
   do{++i; ++c;}
   while(A[i]<x);
   if(i<j)
   {
    t=A[i];
    A[i]=A[j];
    A[j]=t;
   }
   else return j;
  }
 }

 void Q(long l, long r)
 {
  long n;
  if(l<r)
  {
   n=P(l,r);
   Q(l,n);
   Q(n+1,r);
  }
 }

 int main(void)
 {
  c=0;
  for(long i=0; i<N; ++i)
   scanf("%ld", &A[i]);
  Q(0,N-1);
  if(c==(N*N+3*N-4)/2)
   printf
   ("Beutiful Vasilisa");
  else printf
   ("Immortal Koshcei");
  return 0;
 }

请你构造一个数列使得程序输出Beautiful Vasilisa

输入

一行一个整数 n 表示数列长度。

输出

输出n个整数表示你构造的数列,要求是程序能够输出Beautiful Vasilisa

样例输入

3

样例输出

3 7 19

题解

发现这个程序就是快速排序给定的数列,然后统计 i j指针的移动次数和 c 。我们的任务就是构造一个序列使其

c=n2+3n42

由于给定的程序是快速排序,因此我们只关心数列元素之间的大小关系。观察样例输出发现数列是单调增的。因此我们假设严格单调增的数列满足题意。我们构造这样的一个数列,那么执行P时,我们取的 x 为数列片段中的最小值,那么i就从 L1 走到 L j R+1 走到 L ,总共移动了RL+2次。每次 Q(L,R) 调用完 P(L,R) 后,会接着调用 Q(L,L) Q(L+1,R) ,又 Q(L,L)=0 ,所以 Q(0,n1) 相当于

c=0i<n1P(i,n1)=0i<n1(n1)i+2=(n1)(n+1)[0+1++(n2)]=n21[1+(n2)](n2)2=n2+3n42

所以我们构造一个严格单调递增的数列即可

#include <cstdio>

int main() {
    int n, i;
    scanf("%d", &n);
    for (i = 0; i < n; ++i) printf("%d ", i);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值