zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 109 (Rated for Div. 2) A B D 题解

    A. Potion-making

    题意:给你一个k,求k/100化为最简比的分母的值
    思路:签到题,输出100 / gcd(k,100)
    时间复杂度:O tlog100

    #include<bits/stdc++.h>
    #define fer(i,a,b) for(re i = a ; i <= b ; ++ i)
    #define re register int
    #define sf(x) scanf("%d",&x)
    #define sfl(x) scanf("%lld",&x)
    typedef long long ll ;
    using namespace std;
    const int N =  1e6 + 10 , M = 1010 , inf = 0x3f3f3f3f , mod = 1e9 + 7 ;
    int t ;
    int gcd(int a , int b)
    {
        return b ? gcd(b,a%b) : a ;
    }
    int main()
    {
        cin >> t ;
        while(t--)
        {
            int k ;
            cin >> k ;
            cout << 100 / gcd(100,k) << endl;
        }
        return 0;
    }
    

    B. Permutation Sort

    题意:给你一个n的全排列,每次操作可以给任意一个子数组随便排顺序,但是不能给整个数组排序,问将其全部排好序的最小操作数
    思路:思维题 分类讨论
    首先,我的入手点是不能给整个数组排序,
    那我就给下标为1到n-1这个子数组排序,
    或者给下标为2到n这个子数组排序
    那么,如果已经是有序的,就输出0.
    如果a[1]是1的话,给2到n这个子数组排序,操作数是1
    同理,a[n]是n的话,操作数也是1。
    如果不满足上述情况
    在考虑一下
    如果a[n]不是1的话,说明1在前面2到n-1中,我给1到n-1这个子数组排序
    1就会回到1的位置,然后在给2到n这个子数组排序,操作数是2
    同理,a[1] 不等于 n的情况操作数也是2
    其他情况下,操作数一定是3
    证明
    1的位置一定在n中
    给2到n排序
    在给1到n-1排序
    在给2到n排序
    就可以排好序了
    (上面没有说明的数字都是下标)
    时间复杂度:O tn

    #include<bits/stdc++.h>
    #define fer(i,a,b) for(re i = a ; i <= b ; ++ i)
    #define re register int
    #define sf(x) scanf("%d",&x)
    #define sfl(x) scanf("%lld",&x)
    typedef long long ll ;
    using namespace std;
    const int N =  1e6 + 10 , M = 1010 , inf = 0x3f3f3f3f , mod = 1e9 + 7 ;
    int t ;
    int n ;
    int a[N] ;
    int main()
    {
        cin >> t ;
        while(t--)
        {
            cin >> n ;
            fer(i,1,n) sf(a[i]) ;
            if(is_sorted(a + 1 , a + 1 + n))
                puts("0") ;
            else
            {
                if(a[1] == 1 || a[n] == n) puts("1") ;
                else if(a[n] != 1 || a[1] != n) puts("2") ;
                else puts("3") ;
            }
        }
        return 0;
    }
    

    D. Armchairs

    题意:给你一个01数组,如果a[i] == 1 , a[j] == 0 , 把1移动到0所消耗的时间是abs(j-i)
    问把所有的1移动到0的最小时间,并且不能重复移动到同一个位置,
    数据保证1的数量小于等于0的数量。
    思路:很明显是dp,贪心不是最优解
    设f[i][j]表示的是第i个0,当前选取j个1的最小费用。
    设a[]数组表示所有1的位置
    设c[]数组表示所有0的位置
    则f[c[i]][j] = min(f[c[i-1]][j],f[c[i-1]][j-1] + abs(c[i]-a[j]));
    这个方程表达的是对于f[i][j],比较i的上一个位置放了j个1,与第i个位置放了j个1进行比较。
    时间复杂度:O n^2

    #include<bits/stdc++.h>
    #define fer(i,a,b) for(re i = a ; i <= b ; ++ i)
    #define re register int
    #define x first
    #define y second
    #define pb push_back
    #define pll pair<int,int>
    typedef long long ll ;
    using namespace std;
    const int N =  5050 , M = 1010 , inf = 0x3f3f3f3f , mod = 1e9 + 7 ;
    int t , n ;
    int a[N] ;
    int b[N] ;
    int c[N] ;
    int f[N][N] ;
    int main()
    {
     
        cin >> n ;
        fer(i,1,n) cin >> b[i] ;
        
        int k = 0 ;
        fer(i,1,n)
            if(b[i] == 1)
                a[++k] = i ; // 找到所有1的位置
                
        int z = 0 ;
        fer(i,1,n)
            if(b[i] == 0)
                c[++ z] = i ; // 找到所有0的位置
        
        memset(f,0x3f,sizeof f) ;
        
        fer(i,0,N) f[i][0] = 0 ;
        
        for(int i = 1 ; i <= z ; i ++)
        {
            for(int j = 1 ; j <= k ; j ++)
            {
                f[c[i]][j] = min(f[c[i-1]][j],f[c[i-1]][j-1] + abs(c[i]-a[j])) ;
            }
        }
        
        cout << f[c[z]][k] << endl;
     
        return 0;
    }
    
  • 相关阅读:
    CentOS 8.0配置阿里云yum源和epel源
    CentOS8 安装epel 使用阿里云镜像
    centos下yum使用proxy代理方法
    MySQL中的事务控制(一)start transaction
    MySQL中的锁定语句: lock tables 和 unlock tables
    MySQL中的触发器
    MySQL中的事件调度器
    MySQL中的流程控制
    MySQL中的不可见索引、倒序索引
    IDEA出现Push to origin/master was rejected
  • 原文地址:https://www.cnblogs.com/yueshehanjiang/p/14776407.html
Copyright © 2011-2022 走看看