【Baltic2014】【BZOJ3917】Sequence

Description

序列A由从N开始的连续K个数按顺序构成,现在将A中的每个数只保留某一个数码,记为序列B,给定K和B,求可能的最小的N
Input

第一行一个数K,第二行K个数B_i
Output

输出一个数N
Sample Input

6

7 8 9 5 1 2
Sample Output

47
HINT

K<=100000,0<=B_i<=9

N是正整数

Source

APIO强行给此题打广告啊….
此题智商题,我确实不会做
提供一份英文版的官方题解,自己看吧

We’ll solve our task by solving a more complex task first: for each i-th sequence element we’ll declare sequence A_i.
A_i is the sequence of digits which i-th sequence element has to have.
For our initial task, A_i = {d_i}, where d_i - …

Lets donate N = (X)y, where y = N mod 10 is the last digit and X = N div 10.
Now we have to try all possible y values (0, 1, …, 9).
After we have locked y value with one of possible values, our sequence looks like this: (X)y, (X)y+1, …, (X)8, (X)9, (X+1)0, (X+1)1 …, (X+1)8, (X+1)9, (X+2)0, …
After removing last digit, we get sequence X, …, X, X+1, …, X+1, X+2, …

What digits does X has to have?
(X)y has A_1, so X must have A_1 \ {y}. (X)(y+1) has A_2, so X must have A_2 \ {y+1} and so on.

By merging these requirements, we can get a new sequence of sets B_1, B_2, …
B_1 declares required digits for X, B_2 - for (X+1) and so on.
We repeat the same steps with our new sequence.
What happens when we repeat these steps?
We started with sequence length K, so after first step our new sequence length will be not bigger than [K/10]+1.
So after log K steps our sequence will be of length 1 or 2 - at this step we can produce the answer.

Time complexity: O(K*log K)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define MAXN 100010
#define LL long long
#define GET (ch>='0'&&ch<='9')
using namespace std;
int k,b[MAXN];
template <class classname>
inline void in(classname &x)
{
    char ch=getchar();x=0;
    while (!GET)    ch=getchar();
    while (GET) x=x*10+ch-'0',ch=getchar();
}
LL solve(const int a[],int n,bool fla)
{
    LL ret=1ll<<62;
    if (n==1)
    {
        ret=0;
        for (int i=1;i<=9;++i)
            if (a[1]&(1<<i))
            {
                ret=ret*10+i;
                if (ret==i&&(a[1]&1))   ret*=10;
            }
        if (ret==0&&(a[1]&1))   ret=10;
        return ret;
    }
    int tn[MAXN],tp=0;
    for (int i=0;i<9+fla;++i)
    {
        int num=0,now=i;tp=0;bool b=0;
        for (int j=1;j<=n;++j)
        {
            num|=a[j]&(1023-(1<<now));
            if ((a[j]&1)&&now==0)   b=1;
            now++;now=now>=10?now-10:now;
            if (!now||j==n) tn[++tp]=num,num=0;
        }
        LL ans=solve(tn,tp,i<9||n>2)*10+i;
        if (!ans&&b)    ans=10;
        ret=min(ret,ans);
    }
    return ret;
}
int main()
{
    in(k);
    for (int i=1;i<=k;i++)  in(b[i]),b[i]=1<<b[i];
    cout<<solve(b,k,1)<<endl;
}
阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/CreationAugust/article/details/51311798
文章标签: 乱搞
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭