A. Buy the String
题意:01串,买一个0代价c0 ,买一个1代价c1 。可以改变01的值,代价为h。求最小代价。
思路:贪心。如果0变成1再买更便宜就先变成1再买。 1同理。
AC代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 4e5 + 10 ;
const int mod = 1e9 + 7 ;
const int inf = 1e18 ;
int t, n, m, k;
int a[ N] , b[ N] , c[ N] ;
int ans[ N] ;
signed main ( ) {
int t = 1 ; cin>> t;
while ( t-- ) {
int n, c0, c1, h;
cin>> n>> c0>> c1>> h;
string s;
cin>> s;
int res = 0 ;
int cnt0 = 0 ;
int cnt1 = 0 ;
for ( int i = 0 ; i < n ; i ++ ) {
if ( s[ i] == '1' ) cnt1 ++ ;
else cnt0 ++ ;
}
if ( c0+ h <= c1) {
res = cnt0* c0+ ( c0+ h) * cnt1;
} else if ( c1 + h <= c0) {
res = cnt1* c1 + ( c1+ h) * cnt0;
} else {
res = cnt1* c1+ cnt0* c0;
}
cout<< res<< endl; ;
}
return 0 ;
}
B. Sum of Medians
题意:n*k个数,分成k组,求中位数的和。使得和最大为多少。
思路:贪心。从大的开始拿。先拿n/2个,也就是要拿到那个中位数。然后剩下的再拿n/2个。拿k次,就是最大的和了。因为每次都是拿当前最大的n/2,也就是可获得的最大的中位数。小的数不用考虑。 小的数在中位数左边,随便怎么放都行。
AC代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 4e5 + 10 ;
const int mod = 1e9 + 7 ;
const int inf = 1e18 ;
int t, n, m, k;
int a[ N] , b[ N] , c[ N] ;
int ans[ N] ;
signed main ( ) {
int t = 1 ; cin>> t;
while ( t-- ) {
cin>> n>> m;
for ( int i = 1 ; i <= n* m ; i ++ ) {
cin>> a[ i] ;
}
int res = 0 ;
int pos = n* m- n/ 2 ;
for ( int i = n* m- n/ 2 , cnt = 0 ; cnt < m ; cnt++ , i - = n/ 2 + 1 ) {
res + = a[ i] ;
}
cout<< res<< endl;
}
return 0 ;
}
C1. Binary Table (Easy Version)
题意:一个01矩阵。有一种操作。就是选一个2*2的矩阵,然后反转其中三个数。 最后要变成全0的矩阵。求怎么操作。(次数 <= 3*n*m)
思路:可以发现对于一个2*2的矩阵,最多只需要四次,就可以变成全0的了。
AC代码:那就直接按顺序枚举所有矩阵就好了。暴力修改。
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 4e5 + 10 ;
const int mod = 1e9 + 7 ;
const int inf = 1e18 ;
int t, n, m, k;
string s[ N] ;
int a[ 105 ] [ 105 ] ;
struct node{
int x, y;
node ( ) { }
node ( int xx, int yy) : x ( xx+ 1 ) , y ( yy+ 1 ) { } ;
} ;
vector< node> ans;
int count ( int x, int y) {
int res = 0 ;
for ( int i = 0 ; i < 2 ; i ++ ) {
for ( int j = 0 ; j < 2 ; j ++ ) {
res + = a[ x+ i] [ y+ j] ;
}
}
return res;
}
void change ( int x, int y) {
int tmp = count ( x, y) ;
while ( tmp ) {
if ( tmp == 1 ) {
int tmpi;
int tmpj;
for ( int i = 0 ; i < 2 ; i ++ ) {
for ( int j = 0 ; j < 2 ; j ++ ) {
if ( a[ x+ i] [ y+ j] ) {
tmpi = i;
tmpj = j;
ans. push_back ( node ( x+ i, y+ j) ) ;
a[ x+ i] [ y+ j] = 0 ;
}
}
}
int flag = 0 ;
for ( int i = 0 ; i < 2 ; i ++ ) {
for ( int j = 0 ; j < 2 ; j ++ ) {
if ( ! a[ x+ i] [ y+ j] && ( i != tmpi || j != tmpj) ) {
ans. push_back ( node ( x+ i, y+ j) ) ;
a[ x+ i] [ y+ j] = 1 ;
flag ++ ;
if ( flag == 2 ) break ;
}
}
if ( flag == 2 ) break ;
}
}
if ( tmp == 2 ) {
int flag = 0 ;
int tmpi = 0 ;
int tmpj = 0 ;
for ( int i = 0 ; i < 2 ; i ++ ) {
for ( int j = 0 ; j < 2 ; j ++ ) {
if ( a[ x+ i] [ y+ j] ) {
ans. push_back ( node ( x+ i, y+ j) ) ;
tmpi = i;
tmpj = j;
a[ x+ i] [ y+ j] = 0 ;
flag = 1 ;
break ;
}
}
if ( flag) break ;
}
for ( int i = 0 ; i < 2 ; i ++ ) {
for ( int j = 0 ; j < 2 ; j ++ ) {
if ( ! a[ x+ i] [ y+ j] && ( i != tmpi || j != tmpj) ) {
ans. push_back ( node ( x+ i, y+ j) ) ;
a[ x+ i] [ y+ j] = 1 ;
}
}
}
}
if ( tmp == 3 ) {
for ( int i = 0 ; i < 2 ; i ++ ) {
for ( int j = 0 ; j < 2 ; j ++ ) {
if ( a[ x+ i] [ y+ j] ) {
ans. push_back ( node ( x+ i, y+ j) ) ;
a[ x+ i] [ y+ j] = 0 ;
}
}
}
}
if ( tmp == 4 ) {
a[ x] [ y] = 0 ;
a[ x+ 1 ] [ y] = 0 ;
a[ x] [ y+ 1 ] = 0 ;
ans. push_back ( node ( x, y) ) ;
ans. push_back ( node ( x+ 1 , y) ) ;
ans. push_back ( node ( x, y+ 1 ) ) ;
}
tmp = count ( x, y) ;
}
}
signed main ( ) {
int t = 1 ; cin>> t;
while ( t-- ) {
cin>> n>> m;
for ( int i = 0 ; i < n ; i ++ ) cin>> s[ i] ;
for ( int i = 0 ; i < n ; i ++ ) {
for ( int j = 0 ; j < m ; j ++ ) {
a[ i] [ j] = s[ i] [ j] - '0' ;
}
}
ans. clear ( ) ;
for ( int i = 0 ; i < n- 1 ; i ++ ) {
for ( int j = 0 ; j < m- 1 ; j ++ ) {
change ( i, j) ;
}
}
cout<< ans. size ( ) / 3 << endl;
for ( int i = 0 ; i < ans. size ( ) ; i + = 3 ) {
cout<< ans[ i] . x<< " " << ans[ i] . y<< " " ;
cout<< ans[ i+ 1 ] . x<< " " << ans[ i+ 1 ] . y<< " " ;
cout<< ans[ i+ 2 ] . x<< " " << ans[ i+ 2 ] . y<< endl;
}
}
return 0 ;
}
C2. Binary Table (Hard Version)
题意:一个01矩阵。有一种操作。就是选一个2*2的矩阵,然后反转其中三个数。 最后要变成全0的矩阵。求怎么操作。(次数 <= n*m)
思路:题意是一样的,就是操作次数变少了,那就不能枚举所有矩阵了嘛。对于n 或者 m 为奇数的话确实不可以枚举。如果都是偶数依然还是枚举。但是对于奇数呢。其实可以把操作分成两种。一种是只想要修改某一个点的值就好了。一种是把矩阵变成全0,暂且称为操作1。而变成全0的操作其实最多也就4次,这个称为操作2。刚好不会超过题目要求。那么对于n或者m奇数,可以先用操作1,变成一行或者一列全0。因为修改一个点嘛,只要一次就好了。所以也不违背题目要求。剩下的就变成22矩阵了。然后枚举所有2 2矩阵。不要重复枚举就行了。
比赛的时候想歪了。我想的是用操作1把整个矩阵变成只上下一行一列。 再去用操作2暴力反转。但是这样对于小矩阵来说,操作次数会超。大矩阵是可以的。 可恶啊。
AC代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 4e5 + 10 ;
const int mod = 1e9 + 7 ;
const int inf = 1e18 ;
int t, n, m, k;
string s[ N] ;
int a[ 105 ] [ 105 ] ;
struct node{
int x, y;
node ( ) { }
node ( int xx, int yy) : x ( xx+ 1 ) , y ( yy+ 1 ) { } ;
} ;
vector< node> ans;
void show ( ) ;
int count ( int x, int y) {
int res = 0 ;
for ( int i = 0 ; i < 2 ; i ++ ) {
for ( int j = 0 ; j < 2 ; j ++ ) {
res + = a[ x+ i] [ y+ j] ;
}
}
return res;
}
void change ( int x, int y) {
int tmp = count ( x, y) ;
while ( tmp ) {
if ( tmp == 1 ) {
int tmpi;
int tmpj;
for ( int i = 0 ; i < 2 ; i ++ ) {
for ( int j = 0 ; j < 2 ; j ++ ) {
if ( a[ x+ i] [ y+ j] ) {
tmpi = i;
tmpj = j;
ans. push_back ( node ( x+ i, y+ j) ) ;
a[ x+ i] [ y+ j] = 0 ;
}
}
}
int flag = 0 ;
for ( int i = 0 ; i < 2 ; i ++ ) {
for ( int j = 0 ; j < 2 ; j ++ ) {
if ( ! a[ x+ i] [ y+ j] && ( i != tmpi || j != tmpj) ) {
ans. push_back ( node ( x+ i, y+ j) ) ;
a[ x+ i] [ y+ j] = 1 ;
flag ++ ;
if ( flag == 2 ) break ;
}
}
if ( flag == 2 ) break ;
}
}
if ( tmp == 2 ) {
int flag = 0 ;
int tmpi = 0 ;
int tmpj = 0 ;
for ( int i = 0 ; i < 2 ; i ++ ) {
for ( int j = 0 ; j < 2 ; j ++ ) {
if ( a[ x+ i] [ y+ j] ) {
ans. push_back ( node ( x+ i, y+ j) ) ;
tmpi = i;
tmpj = j;
a[ x+ i] [ y+ j] = 0 ;
flag = 1 ;
break ;
}
}
if ( flag) break ;
}
for ( int i = 0 ; i < 2 ; i ++ ) {
for ( int j = 0 ; j < 2 ; j ++ ) {
if ( ! a[ x+ i] [ y+ j] && ( i != tmpi || j != tmpj) ) {
ans. push_back ( node ( x+ i, y+ j) ) ;
a[ x+ i] [ y+ j] = 1 ;
}
}
}
}
if ( tmp == 3 ) {
for ( int i = 0 ; i < 2 ; i ++ ) {
for ( int j = 0 ; j < 2 ; j ++ ) {
if ( a[ x+ i] [ y+ j] ) {
ans. push_back ( node ( x+ i, y+ j) ) ;
a[ x+ i] [ y+ j] = 0 ;
}
}
}
}
if ( tmp == 4 ) {
a[ x] [ y] = 0 ;
a[ x+ 1 ] [ y] = 0 ;
a[ x] [ y+ 1 ] = 0 ;
ans. push_back ( node ( x, y) ) ;
ans. push_back ( node ( x+ 1 , y) ) ;
ans. push_back ( node ( x, y+ 1 ) ) ;
}
tmp = count ( x, y) ;
show ( ) ;
}
}
void show ( ) {
return ;
cout<< "----11-----" << endl;
for ( int i = 0 ; i < n ; i ++ ) {
for ( int j = 0 ; j < m ; j ++ ) {
cout<< a[ i] [ j] ;
}
cout<< endl;
}
cout<< "----22-----" << endl;
}
signed main ( ) {
int t = 1 ; cin>> t;
while ( t-- ) {
cin>> n>> m;
for ( int i = 0 ; i < n ; i ++ ) cin>> s[ i] ;
for ( int i = 0 ; i < n ; i ++ ) {
for ( int j = 0 ; j < m ; j ++ ) {
a[ i] [ j] = s[ i] [ j] - '0' ;
}
}
ans. clear ( ) ;
if ( n& 1 ) {
if ( a[ n- 1 ] [ 0 ] ) {
a[ n- 1 ] [ 0 ] ^ = 1 ;
a[ n- 2 ] [ 0 ] ^ = 1 ;
a[ n- 2 ] [ 1 ] ^ = 1 ;
ans. push_back ( node ( n- 1 , 0 ) ) ;
ans. push_back ( node ( n- 2 , 0 ) ) ;
ans. push_back ( node ( n- 2 , 1 ) ) ;
}
for ( int i = 1 ; i < m ; i ++ ) {
if ( a[ n- 1 ] [ i] ) {
a[ n- 1 ] [ i] ^ = 1 ;
a[ n- 2 ] [ i] ^ = 1 ;
a[ n- 2 ] [ i- 1 ] ^ = 1 ;
ans. push_back ( node ( n- 1 , i) ) ;
ans. push_back ( node ( n- 2 , i) ) ;
ans. push_back ( node ( n- 2 , i- 1 ) ) ;
}
}
show ( ) ;
n -- ;
}
if ( m& 1 ) {
if ( a[ 0 ] [ m- 1 ] ) {
a[ 0 ] [ m- 1 ] ^ = 1 ;
a[ 0 ] [ m- 2 ] ^ = 1 ;
a[ 1 ] [ m- 2 ] ^ = 1 ;
ans. push_back ( node ( 0 , m- 1 ) ) ;
ans. push_back ( node ( 0 , m- 2 ) ) ;
ans. push_back ( node ( 1 , m- 2 ) ) ;
}
for ( int i = 1 ; i < n ; i ++ ) {
if ( a[ i] [ m- 1 ] ) {
a[ i] [ m- 1 ] ^ = 1 ;
a[ i] [ m- 2 ] ^ = 1 ;
a[ i- 1 ] [ m- 2 ] ^ = 1 ;
ans. push_back ( node ( i, m- 1 ) ) ;
ans. push_back ( node ( i, m- 2 ) ) ;
ans. push_back ( node ( i- 1 , m- 2 ) ) ;
}
}
show ( ) ;
m -- ;
}
for ( int i = 0 ; i < n- 1 ; i + = 2 ) {
for ( int j = 0 ; j < m- 1 ; j + = 2 ) {
change ( i, j) ;
}
}
show ( ) ;
cout<< ans. size ( ) / 3 << endl;
for ( int i = 0 ; i < ans. size ( ) ; i + = 3 ) {
cout<< ans[ i] . x<< " " << ans[ i] . y<< " " ;
cout<< ans[ i+ 1 ] . x<< " " << ans[ i+ 1 ] . y<< " " ;
cout<< ans[ i+ 2 ] . x<< " " << ans[ i+ 2 ] . y<< endl;
}
}
return 0 ;
}