A. Yogurt Sale
题意:要购买n个酸奶,有两种买法,一种是一次买一个,价格a。一种是一次买两个,价格b,问买n个酸奶的最小价格。
题解:很容易想到用2a和b比较,判断输出即可。
代码:
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
const int maxn = 4e5 + 7 ;
inline ll read(){
ll x = 0 , f = 1 ;
char c = getchar() ;
while(c > '9' || c < '0'){
if(c == '-')
f = -1 ;
c = getchar() ;
}
while(c >= '0' && c <= '9'){
x = x * 10 + c - '0' ;
c = getchar() ;
}
return x * f ;
}
ll t , n , k , c , a[maxn] ;
ll head[maxn] , nxt[maxn] , ver[maxn] , cnt , ans ;
void solve(){
n = read() ;
k = read() ;
c = read() ;
if(k * 2 <= c){
cout << n * k << endl ;
return ;
}
else{
cout << (n / 2) * c + (n - (n / 2) * 2) * k << endl ;
}
}
int main(){
t = read() ;
while(t --){
solve() ;
}
return 0 ;
}
B. Progressive Square
题意:给你n,c,d,你要生成n*n的矩阵,按照规则。给你n*n个数字,看看能否生成这样的矩阵并且包含所有数字。
题解:用最小数字开始枚举即可,n范围在500,轻松通过。
代码:
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
const int maxn = 1e6 + 7 ;
inline ll read(){
ll x = 0 , f = 1 ;
char c = getchar() ;
while(c > '9' || c < '0'){
if(c == '-')
f = -1 ;
c = getchar() ;
}
while(c >= '0' && c <= '9'){
x = x * 10 + c - '0' ;
c = getchar() ;
}
return x * f ;
}
ll t , n , k , c , a[maxn] ;
ll head[maxn] , nxt[maxn] , ver[maxn] , cnt , ans ;
ll b[550][550] ;
vector < ll > q ;
void solve(){
q.clear() ;
n = read() ;
k = read() ;
c = read() ;
for(int i = 1 ; i <= n * n ; i ++){
a[i] = read() ;
}
sort(a + 1 , a + n * n + 1) ;
ll rt = a[1] ;
b[1][1] = rt ;
for(int i = 2 ; i <= n ; i ++){
b[1][i] = b[1][i - 1] + c ;
}
for(int i = 2 ; i <= n ; i ++){
for(int j = 1 ; j <= n ; j ++){
b[i][j] = b[i - 1][j] + k ;
}
}
for(int i = 1 ; i <= n ; i ++){
for(int j = 1 ; j <= n ; j ++){
q.push_back(b[i][j]) ;
}
}
sort(q.begin() , q.end()) ;
ll Rt = 0 ;
for(int i = 1 ; i <= n * n ; i ++){
if(q[Rt] != a[i]){
cout << "NO\n" ;
return ;
}
Rt ++ ;
}
cout << "YES" << endl ;
}
int main(){
t = read() ;
while(t --){
solve() ;
}
return 0 ;
}
C. Inhabitant of the Deep Sea
题意: 给你n个数字和k,每次怪兽都会按照攻击前面一次再攻击后面一次的顺序攻击,每次造成1滴血量伤害,问最多能击败多少个船。
题解:可以将k分解成两部分,然后枚举统计答案即可。
代码:
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
const int maxn = 1e6 + 7 ;
inline ll read(){
ll x = 0 , f = 1 ;
char c = getchar() ;
while(c > '9' || c < '0'){
if(c == '-')
f = -1 ;
c = getchar() ;
}
while(c >= '0' && c <= '9'){
x = x * 10 + c - '0' ;
c = getchar() ;
}
return x * f ;
}
ll t , n , k , c , a[maxn] ;
ll head[maxn] , nxt[maxn] , ver[maxn] , cnt , ans ;
vector < ll > q ;
void solve(){
n = read() ;
k = read() ;
for(int i = 1 ; i <= n ; i ++){
a[i] = read() ;
}
ll l = (k + 2 - 1) / 2 ;
ll r = k / 2 ;
ll rt = 1 ;
ll ans = 0 ;
while(l != 0){
if(rt > n){
break ;
}
if(l - a[rt] >= 0){
l -= a[rt] ;
ans ++ ;
a[rt] = 0 ;
rt ++ ;
}
else{
a[rt] -= l ;
l = 0 ;
break ;
}
}
rt = n ;
while(r != 0){
if(rt < 1){
break ;
}
if(a[rt] == 0){
break ;
}
if(r - a[rt] >= 0){
r -= a[rt] ;
ans ++ ;
a[rt] = 0 ;
rt -- ;
}
else{
a[rt] -= r ;
r = 0 ;
break ;
}
}
cout << ans << endl ;
}
int main(){
t = read() ;
while(t --){
solve() ;
}
return 0 ;
}
D. Inaccurate Subsequence Search
题意:给你一个数组a和数组b,长度分别为n和m,看看有多少组可以满足满足至少有k个相同的数字?
题解:可以用STL里的map来统计数组b,然后先用map统计1-m的数字有多少相同的,定义,然后每次让l++,r++,统计有多少个相同数字,直接统计答案即可。
代码:
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
const int maxn = 1e6 + 7 ;
inline ll read(){
ll x = 0 , f = 1 ;
char c = getchar() ;
while(c > '9' || c < '0'){
if(c == '-')
f = -1 ;
c = getchar() ;
}
while(c >= '0' && c <= '9'){
x = x * 10 + c - '0' ;
c = getchar() ;
}
return x * f ;
}
ll t , n , k , c , a[maxn] , b[maxn] ;
ll head[maxn] , nxt[maxn] , ver[maxn] , cnt , ans ;
vector < ll > q ;
void solve(){
map < ll , ll > mp , p ;
n = read() ;
k = read() ;
c = read() ;
for(int i = 1 ; i <= n ; i ++){
a[i] = read() ;
}
for(int i = 1 ; i <= k ; i ++){
b[i] = read() ;
mp[b[i]] ++ ;
}
ll sum = 0 , ans = 0 ;
for(int i = 1 ; i <= k ; i ++){
p[a[i]] ++ ;
if(p[a[i]] <= mp[a[i]]){
sum ++ ;
}
}
if(sum >= c){
ans ++ ;
}
ll l = 1 , r = k ;
while(1){
if(r >= n){
break ;
}
if(p[a[l]] - 1 < mp[a[l]]){
sum -- ;
p[a[l]] -- ;
}
else{
p[a[l]] -- ;
}
if(p[a[r + 1]] + 1 <= mp[a[r + 1]]){
sum ++ ;
p[a[r + 1]] ++ ;
}
else{
p[a[r + 1]] ++ ;
}
if(sum >= c){
ans ++ ;
}
l ++ ;
r ++ ;
}
cout << ans << endl ;
}
int main(){
t = read() ;
while(t --){
solve() ;
}
return 0 ;
}
E. Long Inversions
题意:给你一个字符串s,可以选择一个k,每次修改,翻转里面所有的数字,将0变成1,将1变成0,目标是想要将序列全部变成1,。问能满足最大的k是多少。
题解:看到最大的k,先想到了二分,能否从小推大,但是发现不行,那么看到数据,那么可以想到枚举即可,可以通过,首先思考怎么看能否能将所有的数字变成1,很明显从前面到后面依次遍历,如果碰到了0,那么就翻转当前位置i到i + k - 1。那么现在的复杂度是,很明显通过不了。那么就想到了数据结构,那么就想到用树状数组来维护。如果说当前为0,那么就让加1,如果说等于0,那么就区间增加1,如果说等于1那么就不修改,最后遍历一遍看看是否全为1即可。复杂度。
代码:
#include<bits/stdc++.h>
#define ll long long
const int maxn = 5000 + 7 ;
using namespace std;
ll t , n , m , p , l , r , a[maxn] , tree[maxn] ;
char s[maxn];
inline ll read(){
ll x = 0 , f = 1 ;
char c = getchar() ;
while(c > '9' || c < '0'){
if(c == '-')
f = -1 ;
c = getchar() ;
}
while(c >= '0' && c <= '9'){
x = x * 10 + c - '0' ;
c = getchar() ;
}
return x * f ;
}
ll lowbit(ll x){
return x & (-x) ;
}
void update(ll x , ll y){
for( ;x <= n ; x += lowbit(x)){
tree[x] += y ;
}
}
ll Query(ll x){
ll ans = 0 ;
while(x != 0){
ans += tree[x] ;
x -= lowbit(x) ;
}
return ans ;
}
void solve(){
n = read() ;
scanf("%s" , s + 1) ;
for(int i = 1 ; i <= n ; i ++)
a[i] = s[i] - '0' ;
for(int i = n ; i >= 1 ; i --){
for(int j = 0 ; j <= n ; j ++){
tree[j] = 0 ;
}
bool f = 0 ;
for(int j = 1 ; j + i - 1 <= n ; j ++){
ll res = (a[j] + (Query(j) % 2)) % 2 ;
if(res == 0){
update(j , 1) ;
update(j + i , -1) ;
}
}
for(int j = 1 ; j <= n ; j ++){
ll res = (a[j] + (Query(j) % 2)) % 2 ;
if(res == 0){
f = 1 ;
}
}
if(f == 0){
cout << i << endl ;
return ;
}
}
cout << 1 << endl ;
}
int main()
{
t = read() ;
while(t --){
solve() ;
}
return 0;
}
注:也不知道为什么,我一开始用线段树写T了5发,也不知道是我常熟大吗!
F. Unfair Game
题意:给你四个数字,分别代表1,2,3,4的数量,Alice和Bob在进行游戏,如果说所有的数字异或和不为0那么Alice赢,如果说是0那么Bob赢,Eve每次会去掉一个数字,每次都用最优的方式去掉数字,问最多Bob能获胜多少次。
题解:这个题其实很好想,首先可以想到4只要有那么就一定和1,2,3没有任何关系,因为无法组成0,那么就将4的数量单独拿出来看,再看1,2,3的数量,可以想到1和2可以和3抵消掉,然后就可以想出一种方法,就是将1,2,3的数量取min,然后加上4的数量除以2,是一种情况,再看如果说每个的数字是偶数的话,那么很明显比1,2,3抵消要更优,因为每个数字是偶数,如果说是第一种情况最多是2,但是第二种情况每次减2的话答案可以增加3。最后就是特殊的情况,比如1,2,3的数量一样,并且全是奇数,那么答案要加1。如果说三个数字都是奇数,那么答案也要加1。这个题就迎刃而解了。复杂度非常低!
代码:
#include<bits/stdc++.h>
#define ll long long
const int maxn = 5000 + 7 ;
using namespace std;
ll t , n , m , p , l , r , tree[maxn] ;
char s[maxn];
inline ll read(){
ll x = 0 , f = 1 ;
char c = getchar() ;
while(c > '9' || c < '0'){
if(c == '-')
f = -1 ;
c = getchar() ;
}
while(c >= '0' && c <= '9'){
x = x * 10 + c - '0' ;
c = getchar() ;
}
return x * f ;
}
ll a , b , c , d ;
void solve(){
a = read() ;
b = read() ;
c = read() ;
d = read() ;
bool f = 0 ;
if((a == b && b == c && a % 2 == 1) || ((a % 2 == 1) && (b % 2 == 1) && (c % 2 == 1))){
f = 1 ;
}
ll res = (min(min(a , b) , c) + d / 2) ;
ll Res = (a / 2) + (b / 2) + (c / 2) + (d / 2) + ((f == 1) ? 1 : 0) ;
cout << max(res , Res) << endl ;
}
int main()
{
t = read() ;
while(t --){
solve() ;
}
return 0;
}