• HDU 6351 (带技巧的暴力)


    题意:给定一个数,和一个最多交换次数k,问在不超过k次操作的情况,问可以得到的最大值和最小值是多少?

    个人解题的艰辛路程 , 开始是想到了暴力枚举的可能 , 打出来发现在判断枚举的数组与原来数组交换了多少次出现了错误 , 我们扫一遍枚举的数组于原来的数组不相同就往后面找到相同 , 但这个是不行的 , 这样必须是每一位数都不一样才可以 , 然后无耻的看了题解 , O!原来是枚举位置 ,  然后题解,超时了 , 想了想发现当k>cnt 的时候 ,是一定可以构成出来的 ,不需要枚举 , 所以加了这样Ala 

    #include<bits/stdc++.h>
    using namespace std ;
    int A[20],a[20],T[20],sumMAX[20],sumMIN[20];
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            memset(sumMIN,0,sizeof(sumMIN));
            memset(sumMAX,0,sizeof(sumMAX));
            int x,k;
            scanf("%d%d",&x,&k);
            int cnt=0;
            while(x)
            {
    
                a[cnt++]=x%10;
                sumMAX[x%10]++;sumMIN[x%10]++;
                x/=10;
            }
            for(int i=cnt-1 ; i>=0 ; i--)
            {
                A[cnt-1-i]=a[i];
            }
            for(int i=0 ; i<cnt ; i++) a[i]=i;
            int MIN=0x3f3f3f3f,MAX=-1;
            if(k>=cnt-1)///剪枝
            {
                for(int i=1 ; i<=9 ; i++)///第一位排除0
                {
                    if(sumMIN[i])
                    {
                        printf("%d",i);
                        sumMIN[i]--;
                        break;
                    }
                }
                for(int i=0 ; i<=9 ; i++)
                {
                    while(sumMIN[i])
                    {
                        printf("%d",i);
                        sumMIN[i]--;
                    }
                }
                printf(" ");
                for(int i=9 ; i>=0 ; i--)
                {
                    while(sumMAX[i])
                    {
                        printf("%d",i);sumMAX[i]--;
                    }
                }
                puts("");continue;
            }
            do
            {
                int now=0;
                int ans=0;
                if(A[a[0]]==0) continue;
                for(int i=0 ; i<cnt ; i++)
                T[i]=a[i];
                for(int i=0 ; i<cnt ; i++)
                {
                    if(T[i]!=i)
                    {
                        now++;
                        if(now>k) break;
                        for(int j=i+1 ; j<cnt ; j++)
                        {
                            if(T[j]==i)
                            {
                                swap(T[i],T[j]);break;
                            }
                        }
                    }
                    if(now>k) break;
                    ans=ans*10+A[a[i]];
    
                }
                if(now<=k)
                {
                //  printf("%d %d
    ",ans,now);
                  MAX=max(MAX,ans) , MIN=min(MIN,ans);
                }
            } while(next_permutation(a,a+cnt));
            printf("%d %d
    ",MIN,MAX);
    
        }
    }
    View Code
  • 相关阅读:
    硬件设计问题——持续更新
    PCB设计资源整理
    PCB层叠设计和电源分割
    PCB设计技巧
    铜厚电流、Layout 3W原则 20H原则 五五原则
    final关键字
    面向对象——继承与组合
    面向对象——继承
    this总结
    static总结
  • 原文地址:https://www.cnblogs.com/shuaihui520/p/10336483.html
Copyright © 2020-2023  润新知