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;
}