Educational Codeforces Round 109 (Rated for Div. 2) A B D 题解

Posted yueshehanjiang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
}

以上是关于Educational Codeforces Round 109 (Rated for Div. 2) A B D 题解的主要内容,如果未能解决你的问题,请参考以下文章

Educational Codeforces Round 7 A

Educational Codeforces Round 7

Educational Codeforces Round 90

Educational Codeforces Round 33

Codeforces Educational Codeforces Round 54 题解

Educational Codeforces Round 27