A. Buy the String
https://codeforces.com/contest/1440/problem/A
You are given four integers n, c0, c1 and h and a binary string s of length n.
A binary string is a string consisting of characters 0 and 1.
You can change any character of the string s (the string should be still binary after the change). You should pay h coins for each change.
After some changes (possibly zero) you want to buy the string. To buy the string you should buy all its characters. To buy the character 0 you should pay c0 coins, to buy the character 1 you should pay c1 coins.
Find the minimum number of coins needed to buy the string.
Input
The first line contains a single integer t (1≤t≤10) — the number of test cases. Next 2t lines contain descriptions of test cases.
The first line of the description of each test case contains four integers n, c0, c1, h (1≤n,c0,c1,h≤1000).
The second line of the description of each test case contains the binary string s of length n.
Output
For each test case print a single integer — the minimum number of coins needed to buy the string.
Example
input
6
3 1 1 1
100
5 10 100 1
01010
5 10 1 1
11111
5 1 10 1
11111
12 2 1 10
101110110101
2 100 1 10
00
output
3
52
5
10
16
22
Note
In the first test case, you can buy all characters and pay 3 coins, because both characters 0 and 1 costs 1 coin.
In the second test case, you can firstly change 2-nd and 4-th symbols of the string from 1 to 0 and pay 2 coins for that. Your string will be 00000. After that, you can buy the string and pay 5⋅10=50 coins for that. The total number of coins paid will be 2+50=52.
题意
告诉你改变字符的价格,和买两种不同字符的价格,求买完这些字符的价格
思路
将价格和改变价格加买另一种字符价格作比较,取min,求和即可
简单题
代码
#include <bits/stdc++.h>
typedef long long ll;
const ll mod =1e9 + 7;
using namespace std;
namespace fastIO {
inline void input(int& res) {
char c = getchar();res = 0;int f = 1;
while (!isdigit(c)) { f ^= c == '-'; c = getchar(); }
while (isdigit(c)) { res = (res << 3) + (res << 1) + (c ^ 48);c = getchar(); }
res = f ? res : -res;
}
inline ll qpow(ll a, ll b) {
ll ans = 1, base = a;
while (b) {
if (b & 1) ans = (ans * base % mod +mod )%mod;
base = (base * base % mod + mod)%mod;
b >>= 1;
}
return ans;
}
}
using namespace fastIO;
const int N = 1e6+5;
int Case,n,h,c0,c1;
string s;
int main(){
Case=1;
input(Case);
while(Case--){
input(n),input(c0),input(c1),input(h);
int t1=c1,t0=c0;
cin>>s;
if(t0+h<c1) c1=t0+h;
if(t1+h<c0) c0=t1+h;
int ans = 0;
for(int i=0;i<n;i++){
if(s[i]=='0') ans++;
}
printf("%d\n",ans*c0+(n-ans)*c1);
}
return 0;
}
/*
6
3 1 1 1
100
5 10 100 1
01010
5 10 1 1
11111
5 1 10 1
11111
12 2 1 10
101110110101
2 100 1 10
00
*/
B. Sum of Medians
https://codeforces.com/contest/1440/problem/B
A median of an array of integers of length n is the number standing on the ⌈n2⌉ (rounding up) position in the non-decreasing ordering of its elements. Positions are numbered starting with 1. For example, a median of the array [2,6,4,1,3,5] is equal to 3. There exist some other definitions of the median, but in this problem, we will use the described one.
Given two integers n and k and non-decreasing array of nk integers. Divide all numbers into k arrays of size n, such that each number belongs to exactly one array.
You want the sum of medians of all k arrays to be the maximum possible. Find this maximum possible sum.
Input
The first line contains a single integer t (1≤t≤100) — the number of test cases. The next 2t lines contain descriptions of test cases.
The first line of the description of each test case contains two integers n, k (1≤n,k≤1000).
The second line of the description of each test case contains nk integers a1,a2,…,ank (0≤ai≤109) — given array. It is guaranteed that the array is non-decreasing: a1≤a2≤…≤ank.
It is guaranteed that the sum of nk for all test cases does not exceed 2⋅105.
Output
For each test case print a single integer — the maximum possible sum of medians of all k arrays.
Example
input
6
2 4
0 24 34 58 62 64 69 78
2 2
27 61 81 91
4 3
2 4 16 18 21 27 36 53 82 91 92 95
3 4
3 11 12 22 33 35 38 67 69 71 94 99
2 1
11 41
3 3
1 1 1 1 1 1 1 1 1
output
165
108
145
234
11
3
Note
The examples of possible divisions into arrays for all test cases of the first test:
Test case 1: [0,24],[34,58],[62,64],[69,78]. The medians are 0,34,62,69. Their sum is 165.
Test case 2: [27,61],[81,91]. The medians are 27,81. Their sum is 108.
Test case 3: [2,91,92,95],[4,36,53,82],[16,18,21,27]. The medians are 91,36,18. Their sum is 145.
Test case 4: [3,33,35],[11,94,99],[12,38,67],[22,69,71]. The medians are 33,94,38,69. Their sum is 234.
Test case 5: [11,41]. The median is 11. The sum of the only median is 11.
Test case 6: [1,1,1],[1,1,1],[1,1,1]. The medians are 1,1,1. Their sum is 3.
题意
给你n,k,和n*k个有序的数,问n个区间,每个区间长度为k,中位数之和最大值为多少。
思路
这题样例给了好多,能直接看出规律,每个区间要找t = ((n-1)/2)k个数作为每个区间中位数之前的数,然后每(nk-t)/k)相加就是答案。
思维题,不难,做的要快。
代码
#include <bits/stdc++.h>
typedef long long ll;
const ll mod =1e9 + 7;
using namespace std;
namespace fastIO {
inline void input(int& res) {
char c = getchar();res = 0;int f = 1;
while (!isdigit(c)) { f ^= c == '-'; c = getchar(); }
while (isdigit(c)) { res = (res << 3) + (res << 1) + (c ^ 48);c = getchar(); }
res = f ? res : -res;
}
inline ll qpow(ll a, ll b) {
ll ans = 1, base = a;
while (b) {
if (b & 1) ans = (ans * base % mod +mod )%mod;
base = (base * base % mod + mod)%mod;
b >>= 1;
}
return ans;
}
}
using namespace fastIO;
const int N = 1e6+5;
int Case,n,k;
int a[N];
int main(){
Case=1;
input(Case);
while(Case--){
input(n),input(k);
for(int i=1;i<=n*k;i++) input(a[i]);
ll ans = 0;
int t;
if(n==2) t=0;
else t = ((n-1)/2)*k;
//cout<<t<<endl;
//cout<<(n*k-t)/k<<endl;
for(int i=t+1;i<=n*k;i+=(n*k-t)/k) ans += a[i];
printf("%lld\n",ans);
}
return 0;
}
/*
6
2 4
0 24 34 58 62 64 69 78
2 2
27 61 81 91
4 3
2 4 16 18 21 27 36 53 82 91 92 95
3 4
3 11 12 22 33 35 38 67 69 71 94 99
2 1
11 41
3 3
1 1 1 1 1 1 1 1 1
*/
C2. Binary Table (Hard Version)
https://codeforces.com/contest/1440/problem/C2
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
This is the hard version of the problem. The difference between the versions is in the number of possible operations that can be made. You can make hacks if and only if you solved both versions of the problem.
You are given a binary table of size n×m. This table consists of symbols 0 and 1.
You can make such operation: select 3 different cells that belong to one 2×2 square and change the symbols in these cells (change 0 to 1 and 1 to 0).
Your task is to make all symbols in the table equal to 0. You are allowed to make at most nm operations. You don’t need to minimize the number of operations.
It can be proved, that it is always possible.
Input
The first line contains a single integer t (1≤t≤5000) — the number of test cases. The next lines contain descriptions of test cases.
The first line of the description of each test case contains two integers n, m (2≤n,m≤100).
Each of the next n lines contains a binary string of length m, describing the symbols of the next row of the table.
It is guaranteed, that the sum of nm for all test cases does not exceed 20000.
Output
For each test case print the integer k (0≤k≤nm) — the number of operations.
In the each of the next k lines print 6 integers x1,y1,x2,y2,x3,y3 (1≤x1,x2,x3≤n,1≤y1,y2,y3≤m) describing the next operation. This operation will be made with three cells (x1,y1), (x2,y2), (x3,y3). These three cells should be different. These three cells should belong to some 2×2 square.
Example
input
5
2 2
10
11
3 3
011
101
110
4 4
1111
0110
0110
1111
5 5
01011
11001
00010
11011
10000
2 3
011
101
output
1
1 1 2 1 2 2
2
2 1 3 1 3 2
1 2 1 3 2 3
4
1 1 1 2 2 2
1 3 1 4 2 3
3 2 4 1 4 2
3 3 4 3 4 4
4
1 2 2 1 2 2
1 4 1 5 2 5
4 1 4 2 5 1
4 4 4 5 3 4
2
1 3 2 2 2 3
1 2 2 1 2 2
Note
In the first test case, it is possible to make only one operation with cells (1,1), (2,1), (2,2). After that, all symbols will be equal to 0.
In the second test case:
operation with cells (2,1), (3,1), (3,2). After it the table will be:
011
001
000
operation with cells (1,2), (1,3), (2,3). After it the table will be:
000
000
000
In the fifth test case:
operation with cells (1,3), (2,2), (2,3). After it the table will be:
010
110
operation with cells (1,2), (2,1), (2,2). After it the table will be:
000
000
题意
每次只能从2*2的矩阵取三个数,使0变1,1变0。问多少次操作能使其全为0,并输出操作。
口胡思路
这题是困难版,步数小于等于面积,简单版只要小于等于三倍面积,我们来说困难版思路
我们将矩阵分块,分成22,碰到101型就搞,拿22的,2*3的试试就知道了。
代码
#include <bits/stdc++.h>
typedef long long ll;
const ll mod =1e9 + 7;
using namespace std;
namespace fastIO {
inline void input(int& res) {
char c = getchar();res = 0;int f = 1;
while (!isdigit(c)) { f ^= c == '-'; c = getchar(); }
while (isdigit(c)) { res = (res << 3) + (res << 1) + (c ^ 48);c = getchar(); }
res = f ? res : -res;
}
inline ll qpow(ll a, ll b) {
ll ans = 1, base = a;
while (b) {
if (b & 1) ans = (ans * base % mod +mod )%mod;
base = (base * base % mod + mod)%mod;
b >>= 1;
}
return ans;
}
}
using namespace fastIO;
const int N = 1e2+5;
int Case,n,m;
char x;
int a[105][105];
struct node{
int x1;
int y1;
int x2;
int y2;
int x3;
int y3;
};
vector<node> zr;
void cal(int x1,int y1,int x2,int y2,int x3,int y3){
a[x1][y1]^=1,a[x2][y2]^=1,a[x3][y3]^=1;
zr.push_back({x1,y1,x2,y2,x3,y3});
}
void solve(){
input(n),input(m);
zr.clear();
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%c",&x);
a[i][j]=x-'0';
}
getchar();
}
for(int i=2;i<n;i++){
for(int j=2;j<=m;j++){
if(a[i-1][j-1]&&a[i-1][j])
cal(i-1,j-1,i-1,j,i,j-1);
else if(a[i-1][j-1])
cal(i-1,j-1,i,j-1,i,j);
else if(a[i-1][j])
cal(i-1,j,i,j-1,i,j);
}
}
for (int j=2;j<=m;j++){
if(a[n-1][j-1]&&a[n][j-1])
cal(n-1,j-1,n,j-1,n,j);
else if(a[n-1][j-1])
cal(n-1,j-1,n-1,j,n,j);
else if(a[n][j-1])
cal(n,j-1,n-1,j,n,j);
}
if(a[n][m]&&a[n-1][m]){
cal(n,m,n,m-1,n-1,m-1);
cal(n,m-1,n-1,m-1,n-1,m);
}
else if(a[n][m]){
cal(n,m,n,m-1,n-1,m);
cal(n-1,m-1,n,m,n-1,m);
cal(n,m,n-1,m-1,n,m-1);
}
else if(a[n-1][m]){
cal(n-1,m,n-1,m-1,n,m);
cal(n,m,n-1,m,n,m-1);
cal(n-1,m-1,n,m-1,n-1,m);
}
printf("%d\n",zr.size());
for(auto t:zr){
printf("%d %d %d %d %d %d\n",t.x1,t.y1,t.x2,t.y2,t.x3,t.y3);
}
}
int main(){
Case=1;
input(Case);
while(Case--){
solve();
}
return 0;
}
/*
5
2 2
10
11
3 3
011
101
110
4 4
1111
0110
0110
1111
5 5
01011
11001
00010
11011
10000
2 3
011
101
*/