Codeforces Round #653 (Div. 3)A、B、C、D、E1
题目
A题意:给出x,y,n.求不大于n,且mod x = y的最大值.
解法:通过除法向下取整找到最大的数mod x = 0,再加上y.
void solve(){
int x , y , n ;
cin >> x >> y >> n ;
cout << (n-y)/x*x+y << endl;
}
B题意:给出一个数n,两种操作:乘以2或除以6。如果最终能得到1,则输出最小操作次数,否则输出-1.
解法:可以知道该数只能包含2和3质因子,且如果2质因子数大于3,则不可能得到1,否则等于3的因子数加上2和3因子数之差。
void solve(){
int n ;
cin >> n ;
int cnt2 = 0 , cnt3 = 0;
int t = n ;
while(t % 2 == 0){
t /= 2 ;
cnt2++;
}
while(t % 3 == 0){
t /= 3 ;
cnt3++;
}
if(cnt3 >= cnt2 && t == 1){
cout << cnt3 + cnt3-cnt2 << endl;
}else{
cout << -1 << endl;
}
}
C题意:给出一组长为n的括号序列,有操作:将一个括号放到序列最前端,问最小需要几次操作使括号全部正确匹配。
解法:统计不能匹配的括号数量。
void solve(){
int n , sum = 0 , mi = INF;
cin >> n >> s+1;
rep(i , 1 , n){
sum += s[i] == '(' ? 1 : -1 ;
mi = min(mi , sum);
}
cout << -mi << endl;
}
D题意:给出n个数,有两种操作.初始x = 0:1、从数组中选个数加上x,x自加。2、x自加。求使该数组所有数都能被k整除最少操作次数。
解法:考虑出现次数最多且最小(取模后)的那个数。出现次数表示需要循环k次。
void solve(){
int n , k , sum = 0;
cin >> n >> k ;
map<int,int>m;
rep(i , 1 , n){
int x ;
cin >> x ;
x %= k;
if(!x)continue;
sum = max(sum , m[x]*k+k-x+1);
m[x]++;
}
cout << sum << endl;
}
E题意:n本书,每本书需要读\(t_i\)时间,Alice喜好\(a_i\)(0代表不喜欢1代表喜欢),Bob喜好\(b_i\)(上同).
选出一些书,这些书至少包含k本Alice喜欢k本Bob喜欢,问读完这些书至少需要多少时间?
解法:按喜好分四种书00,01,10,11,分别排好序预处理时间前缀和,枚举选择喜好为11的书数量,则01和10也随之确定。
一开始是直接队列模拟虽然a了但代码很丑。
void solve(){
int n , k ;
cin >> n >> k ;
vector<int>v[4] , pre[4];
rep(i , 1 , n){
int t , a , b ;
cin >> t >> a >> b ;
v[a*2+b].pb(t);//分类
}
rep(i , 0 , 3){
sort(all(v[i]));
pre[i].pb(0);
for(auto j : v[i]){
pre[i].pb(pre[i].back()+j);//前缀和
}
}
int ans = 2e9+1 ;
for(int i = 0 ; i < min(k+1 , size(pre[3])) ; i++){//枚举11喜好数量
if(k-i >= size(pre[1]) || k-i >= size(pre[2])) continue;//不符
ans = min(ans , pre[3][i] + pre[1][k-i] + pre[2][k-i]);
}
if(ans == 2e9+1) ans = -1 ;
cout << ans << endl;
}