Educational Codeforces Round 88 (Rated for Div. 2)
A. Berland Poker
题目大意
给n张卡片,其中m张是jokers,把这n张卡片均分给k个人,问怎么分可以使得拥有最多jokers和第二多jokers的人的jokers数量差值最大。输出这个差值。
Solution
首先尽可能把jokers给一个人,如果该人获得卡片数达到上限,剩下的jokers尽可能均分给其余人。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//__builtin_popcount(n);
#define IOS ios::sync_with_stdio(false); cin.tie(0);cout.tie(0)
#define RI register int
const int MOD = 1e9 + 7;
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int SZ = 2e5 + 10;
int n,m,k;
int main()
{
int T;
scanf("%d",&T);
while(T --)
{
scanf("%d%d%d",&n,&m,&k);
int t = n / k;
if(m <= t) printf("%d\n",m);
else
{
int s;
if(((m - t) % (k - 1)) == 0)
s = (m - t) / (k - 1);
else
s = (m - t) / (k - 1) + 1;
printf("%d\n",t - s);
}
}
return 0;
}
B. New Theatre Square
题目大意
把白色区域全部铺上砖,砖有两种类型,一种价值为x的1 x 1的瓷砖,一种价值为y的1 x 2的瓷砖,问怎样铺花费最少。
Solution
如果2x <= y ,全铺第一种。
否则,尽可能多的铺第二种,剩余的空用第一种填。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//__builtin_popcount(n);
#define IOS ios::sync_with_stdio(false); cin.tie(0);cout.tie(0)
#define RI register int
const int MOD = 1e9 + 7;
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int SZ = 2e5 + 10;
int n,m,x,y;
char s[105][1020];
int main()
{
int T;
scanf("%d",&T);
while(T --)
{
int numb = 0,numh = 0;
scanf("%d%d%d%d",&n,&m,&x,&y);
for(int i = 1;i <= n;i ++)
{
getchar();
for(int j = 1;j <= m;j ++)
{
scanf("%c",&s[i][j]);
if(s[i][j] == '.') numb ++;
else if(s[i][j] == '*') numh ++;
}
}
if(2 * x <= y) printf("%d\n",x * numb);
else
{
int ans = 0;
for(int i = 1;i <= n;i ++)
for(int j = 1;j <= m;j ++)
{
if(s[i][j] == '.')
{
if(j + 1 <= m && s[i][j + 1] == '.')
{
numb -= 2;
ans += y;
j ++;
}
}
}
printf("%d\n",ans + numb * x);
}
}
return 0;
}
C. Mixing Water
题目大意
热水的温度是h,冷水的温度是c,目标温度是t。
你可以在一个容器内进行加水操作,使得最终温度尽可能接近t,加水次序必须是热水冷水交替,且第一杯为热水,问最少加几杯水可以使得温度尽可能接近t。
Solution
特殊情况,h == t 输出1.
因为加入水的数量只能是冷水热水相同或者热水比冷水多一杯,所以如果热水影响比冷水大(即热水与目标温度的差值大于目标温度与冷水的差值),那么这个时候多加一杯热水不会使得更靠近目标,直接输出2即可,如果冷水的影响更大,那么就通过加相同数量的冷热水与最终多加的一杯热水抵消来得到更靠近目标温度的效果。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//__builtin_popcount(n);
#define IOS ios::sync_with_stdio(false); cin.tie(0);cout.tie(0)
#define RI register int
const int MOD = 1e9 + 7;
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int SZ = 2e5 + 10;
int h,c,t;
inline void solve()
{
if(h == t) { printf("1\n"); return; }
if(c == t) { printf("2\n"); return; }
int chang1 = h - t ,chang2 = t - c;
if(chang1 == chang2) { printf("2\n"); return; }
int dou = chang1 - chang2;
if(dou > 0) printf("2\n");
else
{
dou = -dou;
int ss = chang1 / dou * dou;
double t1 = (double)abs(chang1 - ss) / (double)(chang1 / dou * 2 + 1);
double t2 = (double)abs(chang1 - (ss + dou)) / (double)(chang1 / dou * 2 + 3);
if(t1 <= t2) printf("%d\n",chang1 / dou * 2 + 1);
else printf("%d\n",(chang1 / dou * 2 + 3));
}
}
int main()
{
int T;
scanf("%d",&T);
while(T --)
{
scanf("%d%d%d",&h,&c,&t);
solve();
}
return 0;
}
D. Yet Another Yet Another Task
题目大意
给定一个长度为n的序列,选择一段连续的区间,去掉其中最大的数字,使得该段区间的和最大。
Solution
a[i]的大小只有30,所以直接枚举一个最大数字,然后暴力扫区间即可。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//__builtin_popcount(n);
#define IOS ios::sync_with_stdio(false); cin.tie(0);cout.tie(0)
#define RI register int
const int MOD = 1e9 + 7;
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int SZ = 2e5 + 10;
int n;
int num[SZ];
int main()
{
/*
int T;
scanf("%d",&T);
while(T --)
{
}
*/
scanf("%d",&n);
int ans = 0;
for(int i = 1;i <= n;i ++) scanf("%d",&num[i]);
for(int i = 1;i <= 30;i ++)
{
int sum = 0;
for(int j = 1;j <= n;j ++)
{
if(num[j] > i)
{
sum = 0;
}
if(num[j] <= i)
{
sum += num[j];
if(sum < 0) sum = 0;
else ans = max(ans,sum - i);
}
}
}
printf("%d\n",ans);
return 0;
}
E. Modular Stability
题目大意
给定一个n和k,从1 - n中选择k个数字,对于任意的数字,对这k个数字取模,不论以什么样的顺序取模,最终结果都一样,求选择的方案数%998244353.
Solution
很明显,如果不论以任何方式取模使得结果一样,则k个数中(从小到大排列),第一个数必须能整除后面的所有数。
那么只要枚举第一个数,然后从可以整除它的数字里面选k - 1个即可。
即为C(n / i - 1,k - 1)的和。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int SZ = 600000 + 10;
const ll MOD = 998244353;
ll n,m;
ll JC[SZ];
inline ll pow_mod(ll a,ll b)
{
ll r = 1;
while(b)
{
if(b & 1) r = (r * a) % MOD;
a = (a * a) % MOD;
b >>= 1;
}
return r;
}
inline ll C(ll n,ll m)
{
if(m > n) return 0;
return ((JC[n] * pow_mod(JC[m],MOD - 2)) % MOD * pow_mod(JC[n - m],MOD - 2) % MOD);
}
/*
inline ll Lucas(ll n,ll m)
{
if(!m) return 1;
return C(n % p,m % p) * Lucas(n / p, m / p) % p;
}
*/
inline void get_JC()
{
JC[0] = 1;
for(int i = 1;i <= n;i ++) JC[i] = (JC[i - 1] * i) % MOD;
}
int main()
{
scanf("%lld%lld",&n,&m);
get_JC();
ll ans = 0;
for(int i = 1;i <= n;i ++)
{
if(n / i < m) continue;
ans = (ans + C(n / i - 1,m - 1)) % MOD;
}
printf("%lld\n",ans);
}
2020.5.29