• 清北集训Day3T1(转换)


    这题可能是我与正解里的最近的一次了,可以还是sb的把正解叉了。

    正解其实比较显然:因为$f(x)$只有81个取值,所以我们可以枚举$f(x)$,然后计算$x$,再判断$x$是否可以转化为$f(x)$

    刚开始以为一个$f(x)$会对应很多$x$,所以这么枚举是错的。

    但实际上我们在枚举$f(x)$的时候并不关注$f(x)$与$x$的关系,因此我们可以直接把$f(x)$看做与$x$毫不相关的变量$y$

    这样枚举出$y$对应的$x$后再判断$f(y)$是否等于$x$,这样就一定是对的了

    // luogu-judger-enable-o2
    // luogu-judger-enable-o2
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int MAXN=1e6+10;
    #define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
    char buf[1<<20],*p1=buf,*p2=buf;
    inline int read()
    {
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int ans[MAXN],tot;
    int f(int a,int p)
    {
        int base=0,ans=1;
        while(a) base+=a%10,a/=10;
        for(int i=1;i<=p;i++) 
            ans=ans*base;
        return ans;
    }
    int a1[50]={10,0,1,2,3,4,5,6,7,8,9};
    int a2[50]={3,0,1,81};
    int a3[50]={7,0,1,512,4913,5832,17576,19683};
    int a4[50]={7,0,1,2401,234256,390625,614656,1679616};
    int a5[50]={6,0,1,17210368,52521875,60466176,205962976};
    int main()
    {
        int T=read();
        while(T--)
        {
            int a=read(),b=read(),c=read(),k=read();
            if(a==1&&c==0)
            {
                tot=0;
                //f(x)^a * b + c = x 
                k=min(k,(int)1e6);
                for(int i=0;i<=k;i++)
                    if(f(i,a) * b + c == i) 
                        ans[++tot]=i;
                if(tot==0) {printf("0
    -1
    ");continue;}
                printf("%d
    ",tot);
                for(int i=1;i<=tot;i++)
                    printf("%d ",ans[i]);puts("");
            }
            else if(b==1&&c==0)
            {
                if(a==1)
                {
                    int ans=0;
                    for(int i=1;i<=a1[0];i++)
                        if(a1[i]<=k)
                            ans++;
                    if(ans==0) {printf("0
    -1
    ");continue;}
                    printf("%d
    ",ans);
                    for(int i=1;i<=ans;i++)
                        printf("%d ",a1[i]);printf("
    ");
                }
                else if(a==2)
                {
                    int ans=0;
                    for(int i=1;i<=a2[0];i++)
                        if(a2[i]<=k)
                            ans++;
                    if(ans==0) {printf("0
    -1
    ");continue;}
                    printf("%d
    ",ans);
                    for(int i=1;i<=ans;i++)
                        printf("%d ",a2[i]);printf("
    ");
                }
                else if(a==3)
                {
                    int ans=0;
                    for(int i=1;i<=a3[0];i++)
                        if(a3[i]<=k)
                            ans++;
                    if(ans==0) {printf("0
    -1
    ");continue;}
                    printf("%d
    ",ans);
                    for(int i=1;i<=ans;i++)
                        printf("%d ",a3[i]);printf("
    ");
                }
                else if(a==4)
                {
                    int ans=0;
                    for(int i=1;i<=a4[0];i++)
                        if(a4[i]<=k)
                            ans++;
                    if(ans==0) {printf("0
    -1
    ");continue;}
                    printf("%d
    ",ans);
                    for(int i=1;i<=ans;i++)
                        printf("%d ",a4[i]);printf("
    ");
                }
                else if(a==5)
                {
                    int ans=0;
                    for(int i=1;i<=a5[0];i++)
                        if(a5[i]<=k)
                            ans++;
                    if(ans==0) {printf("0
    -1
    ");continue;}
                    printf("%d
    ",ans);
                    for(int i=1;i<=ans;i++)
                        printf("%d ",a5[i]);printf("
    ");
                } 
            }
            else
            {
                tot=0;
                //f(x)^a * b + c = x
                for(int i=0;i<=k;i++)
                    if(f(i,a) * b + c == i) 
                        ans[++tot]=i;
                if(tot==0) {printf("0
    -1
    ");continue;}
                printf("%d
    ",tot);
                for(int i=1;i<=tot;i++)
                    printf("%d ",ans[i]);puts("");            
            }
    
        }
        return 0;
    }
    80分暴力
    // luogu-judger-enable-o2
    #include<cstdio>
    #include<algorithm>
    #include<vector>
    #define int long long 
    using namespace std;
    const int MAXN=1e6+10;
    //#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
    //char buf[1<<20],*p1=buf,*p2=buf;
    inline int read()
    {
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    vector<int>v;
    int check(int x)
    {
        int base=0;
        while(x) base+=x%10,x/=10;
        return base;
    }
    main()
    {
        int T=read();
        while(T--)
        {
            int a=read(),b=read(),c=read(),k=read();
            v.clear();
            for(int i=0;i<=81;i++)
            {
                int x=i;
                for(int j=1;j<a;j++) x=x*i;
                x=x*b+c;
                if(x<0||x>=k||check(x)!=i) continue;
                v.push_back(x);
            }
            if(v.size()==0) {printf("0
    -1
    ");continue;}
            printf("%d
    ",v.size());
            for(int i=0;i<v.size();i++)
                printf("%d ",v[i]);
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    SPLAY,LCT学习笔记(五)
    SPLAY,LCT学习笔记(四)
    SPLAY,LCT学习笔记(三)
    NOI 2012 随机数生成器
    SPLAY,LCT学习笔记(二)
    SPLAY,LCT学习笔记(一)
    bzoj 1503 郁闷的出纳员
    bzoj 1112 poi 2008 砖块
    bzoj 1064 noi2008 假面舞会题解
    数论知识点总结(noip范围)
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/8652358.html
Copyright © 2020-2023  润新知