Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

请大牛看一下,我几百组数据都过了,为什么还是wa?

Posted by hncu793116483 at 2013-12-05 18:17:16 on Problem 1833
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 1030
int len,k,a[N],lct[N][N],sum[N][N],in[9]= {1,1,2,6,24,120,720,5040,40320};
int tree[4*N];
void builde(int l,int r,int v)
{
    int m=(l+r)>>1;
    tree[v]=0;
    if(l==r)return ;
    builde(l,m,v<<1);
    builde(m+1,r,v<<1|1);
}
int updata(int l,int r,int v,int id)
{
    int m=(l+r)>>1;
    tree[v]++;
    if(l==r)return 0;
    if(id<=m) return updata(l,m,v<<1,id)+tree[v<<1|1];
    else return updata(m+1,r,v<<1|1,id);
}
int cmp(int a,int b)
{
    return a<b;
}
int cmp1(int a,int b)
{
    return a>b;
}
void xchg(int &a,int &b)
{
    int t;
    t=a;
    a=b;
    b=t;
}
int find(int i)//找出比a[i]大的数中最小的位置
{
    int l;
    for(l=i+1; l<len; l++)
        if(a[i]<a[l]) return l;
}
void print(int l,int r)//输出l~r的数
{
    for(; l<=r; l++)
        if(l!=0) printf(" %d",a[l]);
        else printf("%d",a[l]);
}
void setlct()//以数值从小到大的序列为目标,计算出每个sum,lct对应的大小
{
    for(len=1024; len>=1; len--)
    {
        sum[len][len-1]=0; sum[len][len]=0;
        for(int j=len-2; j>=0; j--)
        {
            lct[len][j]=len-j-1;//j后有len-j-1个数比a[j]大
            sum[len][j]=sum[len][j+1];//位置j排列种数,越靠左的sum越大
            if(len-j<=9)
                sum[len][j]+=lct[len][j]*in[len-j-1];
        }
    }
}
int two(int l,int r,int ln)//找到sum[ln]中比k值大的数中最小的位置
{
    for(; r>=l; r--)
        if(sum[ln][r]>=k)
            return r;
}
void ssss(int l,int ln)
{
    if(l>=len) return ;
    int i;
    i=two(l,len-1,ln);
    k-=sum[ln][i+1];//printf("k=%d ",k);
    print(l,i-1);
    l=i;
    int m=k/in[len-i-1],j,flog=0;
    if(k%in[len-i-1]) {m++,flog=1;}
    sort(a+i+1,a+len,cmp);
    j=find(i);
    if(j>i)xchg(a[i],a[j+m-1]);
    print(l,i);
    l=i+1;
    k-=(m-flog)*in[len-i-1];
    if(k==0)
    {
        sort(a+l,a+len,cmp1);
        print(l,len-1);
        l=len;
        return;
    }
    else
    {
        k--;
        sort(a+l,a+len,cmp);
        if(k==0)
        {
            print(l,len-1);
            l=len;
            return ;
        }
    }
    while(sum[len][l]<k)k-=sum[len][l];
    if(k>0) ssss(l,len);
}
int main()
{
    int t,l,i,r,max,v;
    //位置i的组合数=后方比位置i的值大的个数*(len-i)!
    setlct();
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&len,&k);
        sum[0][len]=0;
        r=len-1; max=0;
        for( i=0; i<len; i++)
        {
            scanf("%d",&a[i]);lct[0][i]=0;
            if(max<a[i])max=a[i];
        }
        if(len==1||k==0)
        {
            print(0,len-1);printf("\n");
            continue;
        }
        builde(1,max,1);
        for( i=len-1; i>=0; i--)
        {
            lct[0][i]=updata(1,max,1,a[i]);
            sum[0][i]=sum[0][i+1];
            if(len-i<=9) sum[0][i]+=lct[0][i]*in[len-i-1];
            if(lct[0][i]&&len-r<9) r=i;
        }
        l=0;
        v=0;
        if(sum[v][l]>=k&&k>0)
        {
            ssss(l,v);
        }
        else while(k>0)
        {
            k-=sum[v][l];
            if(len-r>=9)
            {
                print(l,r);
                l=r+1;
                r=len;
            }
            sort(a+l,a+len,cmp);
            k--;
            if(k==0)
            {
                print(l,len-1);
                l=len;
                break;
            }
            else
            {
                v=len;
                if(sum[v][l]>=k)
                {
                    ssss(l,len);
                    break;
                }
            }
        }
        printf("\n");
    }
    return 0;
}

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator