zoukankan      html  css  js  c++  java
  • 【考试】8.18【未完成】

    一场爆零的考试。

    记住这个惨痛的教训。

    1>心有灵犀

    大意:给你一个不超过 10^9 的数字 n 和一个交换次数上限 k,

    每次操作对这个 数字 n 的其中两位进行交换,

    求出交换后最 大的数字和最小的数字的差的绝对值。

    要点:

    1. 某一位的数字可以和它本身进行交换

    2. 交换的数字不可以有前导零(即第一位不可以是 0)

    解法:

    1)如果这个数字是 n 位数,那么其交换不超过 n-1 次就可以变成最大值和最小值

    可以根据这个点进行剪枝。

    2)题目给的数字不超过 10^9,那么进行全排列直接暴力就好了, 时间复杂度最多 9!

    我是怎么爆零的:贪心......

    以后记得先算最大的时间复杂度,再贪心......

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    string n;
    int k,len,d[13];
    
    void work()
    {
        for(int i=0;i<len;i++)
            d[i]=n[i]-'0';
        sort(d,d+len);
        int mx=d[len-1];
        for(int i=len-2;i>=0;i--)
            mx=(mx<<3)+(mx<<1)+d[i];
        
        d[len]=0;
        if(!d[0])
        {
            int pos=1;
            while(pos<len && !d[pos]) pos++;
            swap(d[0],d[pos]);
        }
        int mn=d[0];
        for(int i=1;i<len;i++) mn=(mn<<3)+(mn<<1)+d[i];
        printf("%d
    ",mx-mn);
    }
    string ans_mx,ans_mn;
    void dfs(string nw,int tm,int pos)
    {
        if(tm==k)
        {
            ans_mx=max(ans_mx,nw);
            ans_mn=min(ans_mn,nw);
            return ;
        }
        else if(pos>=len) return ;
        else
        {
            ans_mx=max(ans_mx,nw);
            ans_mn=min(ans_mn,nw);
            
            int i=pos;
            for(int j=i+1;j<len;j++)
            {
                if(!i && nw[j]=='0') continue;
                swap(nw[i],nw[j]);
                dfs(nw,tm+1,pos+1);
                swap(nw[i],nw[j]);
            }
            dfs(nw,tm,pos+1);
        }
    }
    
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            cin>>n;
            scanf("%d",&k);
            len=n.length() ;
            if(k>=len-1) work();
            else 
            {
                ans_mn=ans_mx=n;
                dfs(n,0,0);
                int ans=0;
                for(int i=0;i<len;i++)
                    ans=(ans<<3)+(ans<<1)+ans_mx[i]-ans_mn[i];
                printf("%d
    ",ans);
            }
        }
        
        return 0;
    } 


    2>不服来战

    你有一列 N 盏灯,初始时有些是开的,有些是关的。

    每盏灯有各自的权值。每次操作你可以改变任意连续 K 盏灯的开关状态。

    你可以操作任意多次,求最终 最大的 亮着的灯的权值和。

    解法:

    转换思路:每次改变连续k盏灯,

    那么分为操作一次和连着操作两次:

    1)改变 i - i+k-1 盏灯的状态

    2)改变 i 和 i+k 的状态

    然后发现:可以将灯进行分组:

    1,1+k,1+k*2,1+k*3...

    1,2,2+k,2+k*2...

    组与组之间(除了开头与结尾的 两个点 以外)没有影响!

    再稍作分析,不难发现,如果一组内“初始时是关的”的灯为偶数个,

    那么我们可以 做到只把它们全部打开;

    如果一组内“初始时是关的” 的灯为奇数个,这个时候我们不能把所有的灯都打开,只好作出让步,选择放弃亮度最小 的那盏灯。

    每一组都如此处理,最后加起来。

    关于开头结尾两个点,我们通过枚举 是否在开始时^(1-k)个点的状态,那么最后的点就会随之改变

    (其实不太懂这一段)

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    using namespace std;
    int t,n,k,sum;
    const int N=1003;
    bool f[N];
    int v[N];
    
    int get()
    {
        int nw=sum;
        for(int i=1;i<=k&& i<=n;i++)
        {
            bool cnt=false;
            int mn=2000;
            for(int j=i;j<=n;j+=k)
            {
                if(!f[j]) cnt^=1;
                mn=min(mn,v[j]);
            } 
            if(cnt) nw-=mn; 
        }
        return nw;
    }
    
    int main()
    {
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&k);
            sum=0,f[n+1]=false,v[n+1]=0;
            int x;
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&x);
                if(x) f[i]=true;
                else f[i]=false;
            }
            for(int i=1;i<=n;i++)
                scanf("%d",&v[i]),sum+=v[i];
            
            int ans=get();
            for(int i=1;i<=k;i++) f[i]^=1;
            ans=max(ans,get());
            
            printf("%d
    ",ans);
        }
        
        return 0;
    }

    3>铁路网络

    等下

  • 相关阅读:
    文件输入使System.out.println("程序执行完毕!");这句话的内容输入到文件中
    TI CC2541.h的头文件 for IAR
    状态添加Android游戏开发十日通(4)行走,跳跃,碰撞检测
    命令分析分析企业内连接Exchange 移动设备!
    寄存器数据问题反馈集锦W5200/W5300相关
    发票选择SAP 校验发票时:科目5101140100已设置为与税务不相关
    重写方法Android中的HttpsURLConnection连接
    生成数组C面试题精选
    函数路径Croc Champ 2013 Round 2 题解java教程
    排名中国重读“发展Linux,中日两国之比较”有感java教程
  • 原文地址:https://www.cnblogs.com/xwww666666/p/11524394.html
Copyright © 2011-2022 走看看