Codeforces Round #684 (Div. 2)

Codeforces Round #684 (Div. 2)

传送门(点击传送

A. Buy the String

题意:
  有长度为n的二进制串,你可以花费h的价格把任意一位置反( 1 改 0 ,0 改 1 )。然后你要买下这个二进制串,每个 1 你需要花费 c 1 c_1 c1 元,每个 0 你需要花费 c 0 c_0 c0 元。问最少需要多少钱可以买下二进制串。( t 组数据)
  
思路:
  枚举整个串有 0 个 0 到有 n 个 0 ,其中的最小值即为答案。
  
代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
int main()
{
    
    
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int t,n,c0,c1,h;
    string s;
    cin>>t;
    while(t--){
    
    
        int ans=0x7fffffff,cont0=0,sum;
        cin>>n>>c0>>c1>>h;
        cin>>s;
        for(int i=0;i<n;i++){
    
    
            if(s[i]=='0')cont0++;
        }
        for(int i=0;i<=n;i++){
    
    
            sum=abs(cont0-i)*h;
            sum+=i*c0+(n-i)*c1;
            ans=min(ans,sum);
        }
        cout<<ans<<endl;
    }
    return 0;
}

B. Sum of Medians

题意:
  有一个序列有 n × k n\times k n×k个元素,现在让你把这个序列分成 k 组,每组的中位数为该组从小到大排序后的第 ⌈ n 2 ⌉ \left \lceil \frac{n}{2} \right \rceil 2n个数,现在让求出所有中位数之和的最大值是多少。( t 组数据)

思路:
  贪心,先把所有数排序,把前面的 ⌊ n − 1 2 ⌋ × k \left \lfloor \frac{n-1}{2} \right \rfloor \times k 2n1×k 个数放在每组的中位之前,这样可以保证最小的数都不被用到,之后每放置一个中位数,中位数后都放置比它大的尽量小的数。即可求得最大值。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
int num[maxn];
int main()
{
    
    
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int t,n,k;
    cin>>t;
    while(t--){
    
    
        cin>>n>>k;
        for(int i=1;i<=n*k;i++){
    
    
            cin>>num[i];
        }
        sort(num+1,num+1+n*k);
        ll ans=0;
        int loc=(n-1)/2*k;
        for(int i=loc+1;i<=n*k;i+=n-(n-1)/2){
    
    
            ans+=1ll*num[i];
        }
        cout<<ans<<endl;
    }
    return 0;
}

C1. Binary Table (Easy Version)

题意:
  有 n × m n \times m n×m的二进制矩阵,你每次操作可以选一个 2 × 2 2\times2 2×2的矩阵,把其中的三个元素取反( 1 改 0 ,0 改 1 )。最多操作 3 n m 3nm 3nm 次,把所有元素都改为 0 ,请输出操作次数和每次操作选的 3 个位置。( t 组数据)

思路:
  对于 2 × 2 2\times2 2×2的格子的所有情况,除了全是 1 的情况外,所有情况皆可以在操作3次及3次以内让所有元素变为 0 ,所以我们对每个 2 × 2 2\times2 2×2的格子进行情况匹配即可完成。我们分为如下4个操作:每个操作都是红色区域取反。
在这里插入图片描述
一共16中情况我们可以分别考虑:

  1. 全为0:不用操作。
  2. 左上角为1,其余为0:进行操作1,操作2,操作3。
  3. 右上角为1,其余为0:进行操作2,操作1,操作4。
  4. 左下角为1,其余为0:进行操作3,操作1,操作4。
  5. 右下角为1,其余为0:进行操作4,操作2,操作3。
  6. 左上右上为1:进行操作3,操作4。
  7. 左上左下为1:进行操作2,操作4。
  8. 左上右下为1:进行操作1,操作4。
  9. 右上左下为1:进行操作2,操作3。
  10. 右上右下为1:进行操作1,操作3。
  11. 左下右下为1:进行操作1,操作2。
  12. 左上,右上,左下为1:进行操作1。
  13. 左上,右上,右下为1:进行操作2。
  14. 左上,左下,右下为1:进行操作3。
  15. 右上,左下,右下为1:进行操作4。
  16. 全为1:进行操作4,操作1,操作2,操作3。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=110;
char c[maxn][maxn];
vector<pair<int,int> >vec;
int t,n,m;
void change1(int x,int y){
    
    
    vec.push_back({
    
    x,y});vec.push_back({
    
    x,y+1});vec.push_back({
    
    x+1,y});
}
void change2(int x,int y){
    
    
    vec.push_back({
    
    x,y});vec.push_back({
    
    x,y+1});vec.push_back({
    
    x+1,y+1});
}
void change3(int x,int y){
    
    
    vec.push_back({
    
    x,y});vec.push_back({
    
    x+1,y});vec.push_back({
    
    x+1,y+1});
}
void change4(int x,int y){
    
    
    vec.push_back({
    
    x,y+1});vec.push_back({
    
    x+1,y});vec.push_back({
    
    x+1,y+1});
}
void solve(int x,int y){
    
    
    if(c[x][y]=='0' && c[x][y+1]=='0' && c[x+1][y]=='0' && c[x+1][y+1]=='0'){
    
    
        return;
    }else if(c[x][y]=='1' && c[x][y+1]=='0' && c[x+1][y]=='0' && c[x+1][y+1]=='0'){
    
    
        change1(x,y);change2(x,y);change3(x,y);
    }else if(c[x][y]=='0' && c[x][y+1]=='1' && c[x+1][y]=='0' && c[x+1][y+1]=='0'){
    
    
        change2(x,y);change1(x,y);change4(x,y);
    }else if(c[x][y]=='0' && c[x][y+1]=='0' && c[x+1][y]=='1' && c[x+1][y+1]=='0'){
    
    
        change3(x,y);change1(x,y);change4(x,y);
    }else if(c[x][y]=='0' && c[x][y+1]=='0' && c[x+1][y]=='0' && c[x+1][y+1]=='1'){
    
    
        change4(x,y);change2(x,y);change3(x,y);
    }else if(c[x][y]=='1' && c[x][y+1]=='1' && c[x+1][y]=='0' && c[x+1][y+1]=='0'){
    
    
        change3(x,y);change4(x,y);
    }else if(c[x][y]=='1' && c[x][y+1]=='0' && c[x+1][y]=='1' && c[x+1][y+1]=='0'){
    
    
        change2(x,y);change4(x,y);
    }else if(c[x][y]=='1' && c[x][y+1]=='0' && c[x+1][y]=='0' && c[x+1][y+1]=='1'){
    
    
        change1(x,y);change4(x,y);
    }else if(c[x][y]=='0' && c[x][y+1]=='1' && c[x+1][y]=='1' && c[x+1][y+1]=='0'){
    
    
        change2(x,y);change3(x,y);
    }else if(c[x][y]=='0' && c[x][y+1]=='1' && c[x+1][y]=='0' && c[x+1][y+1]=='1'){
    
    
        change1(x,y);change3(x,y);
    }else if(c[x][y]=='0' && c[x][y+1]=='0' && c[x+1][y]=='1' && c[x+1][y+1]=='1'){
    
    
        change1(x,y);change2(x,y);
    }else if(c[x][y]=='1' && c[x][y+1]=='1' && c[x+1][y]=='1' && c[x+1][y+1]=='0'){
    
    
        change1(x,y);
    }else if(c[x][y]=='1' && c[x][y+1]=='1' && c[x+1][y]=='0' && c[x+1][y+1]=='1'){
    
    
        change2(x,y);
    }else if(c[x][y]=='1' && c[x][y+1]=='0' && c[x+1][y]=='1' && c[x+1][y+1]=='1'){
    
    
        change3(x,y);
    }else if(c[x][y]=='0' && c[x][y+1]=='1' && c[x+1][y]=='1' && c[x+1][y+1]=='1'){
    
    
        change4(x,y);
    }else if(c[x][y]=='1' && c[x][y+1]=='1' && c[x+1][y]=='1' && c[x+1][y+1]=='1'){
    
    
        change4(x,y);change1(x,y);change2(x,y);change3(x,y);
    }
    c[x][y]='0';c[x+1][y]='0';c[x][y+1]='0';c[x+1][y+1]='0';
}
int main()
{
    
    
    scanf("%d",&t);
    while(t--){
    
    
        vec.clear();
        scanf("%d %d\n",&n,&m);
        for(int i=1;i<=n;i++){
    
    
            scanf("%s",c[i]+1);
        }
        for(int i=1;i<n;i++){
    
    
            for(int j=1;j<m;j++){
    
    
                solve(i,j);
            }
        }
        printf("%d\n",vec.size()/3);
        for(int i=0;i<vec.size();i+=3){
    
    
            printf("%d %d %d %d %d %d\n",vec[i].first,vec[i].second,vec[i+1].first,vec[i+1].second,vec[i+2].first,vec[i+2].second);
        }
    }
    return 0;
}

C2. Binary Table (Hard Version)

题意:
  上一题的困难版本有 n × m n \times m n×m的二进制矩阵,你每次操作可以选一个 2 × 2 2\times2 2×2的矩阵,把其中的三个元素取反( 1 改 0 ,0 改 1 )。最多操作 n m nm nm 次,把所有元素都改为 0 ,请输出操作次数和每次操作选的 3 个位置。( t 组数据)
  
思路:
  我们还是一行一行改,除最后两行外,我们每一个 2 × 2 2\times2 2×2的矩阵如果矩阵的左上角为1,那么我们都采取如下几种操作:若右上为1,则采用操作1,否则采用操作3。对于最右边的 2 × 2 2\times2 2×2矩阵我们要单独判断,若右上为1则采用操作4。就这样,我们把所有的 1 转移到最后两行。对于最后两行,我们从左往右枚举 2 × 2 2\times2 2×2矩阵,若左上左下都为1,则采用操作1;若左上为1左下为0,则采用操作2;若左上为0,左下为1则采用操作4。如此操作我们将所有的1转移到最右边的矩阵中。最后对最右边的 2 × 2 2\times2 2×2矩阵做处理即可。操作次数最多为 ( ⌊ m 2 ⌋ + 1 ) × ( n − 2 ) + ( m − 2 ) + 4 (\left \lfloor \frac{m}{2} \right \rfloor+1)\times(n-2)+(m-2)+4 (2m+1)×(n2)+(m2)+4是小于 n m nm nm的。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=110;
char c[maxn][maxn];
vector<pair<int,int> >vec;
int t,n,m;
void make_solve(int x,int y){
    
    
    if(c[x][y]=='1') c[x][y]='0';
    else c[x][y]='1';
}
void change1(int x,int y){
    
    
    vec.push_back({
    
    x,y});vec.push_back({
    
    x,y+1});vec.push_back({
    
    x+1,y});
    make_solve(x,y);make_solve(x,y+1);make_solve(x+1,y);
}
void change2(int x,int y){
    
    
    vec.push_back({
    
    x,y});vec.push_back({
    
    x,y+1});vec.push_back({
    
    x+1,y+1});
    make_solve(x,y);make_solve(x,y+1);make_solve(x+1,y+1);
}
void change3(int x,int y){
    
    
    vec.push_back({
    
    x,y});vec.push_back({
    
    x+1,y});vec.push_back({
    
    x+1,y+1});
    make_solve(x,y);make_solve(x+1,y);make_solve(x+1,y+1);
}
void change4(int x,int y){
    
    
    vec.push_back({
    
    x,y+1});vec.push_back({
    
    x+1,y});vec.push_back({
    
    x+1,y+1});
    make_solve(x,y+1);make_solve(x+1,y);make_solve(x+1,y+1);
}
void solve(int x,int y){
    
    
    if(c[x][y]=='0' && c[x][y+1]=='0' && c[x+1][y]=='0' && c[x+1][y+1]=='0'){
    
    
        return;
    }else if(c[x][y]=='1' && c[x][y+1]=='0' && c[x+1][y]=='0' && c[x+1][y+1]=='0'){
    
    
        change1(x,y);change2(x,y);change3(x,y);
    }else if(c[x][y]=='0' && c[x][y+1]=='1' && c[x+1][y]=='0' && c[x+1][y+1]=='0'){
    
    
        change2(x,y);change1(x,y);change4(x,y);
    }else if(c[x][y]=='0' && c[x][y+1]=='0' && c[x+1][y]=='1' && c[x+1][y+1]=='0'){
    
    
        change3(x,y);change1(x,y);change4(x,y);
    }else if(c[x][y]=='0' && c[x][y+1]=='0' && c[x+1][y]=='0' && c[x+1][y+1]=='1'){
    
    
        change4(x,y);change2(x,y);change3(x,y);
    }else if(c[x][y]=='1' && c[x][y+1]=='1' && c[x+1][y]=='0' && c[x+1][y+1]=='0'){
    
    
        change3(x,y);change4(x,y);
    }else if(c[x][y]=='1' && c[x][y+1]=='0' && c[x+1][y]=='1' && c[x+1][y+1]=='0'){
    
    
        change2(x,y);change4(x,y);
    }else if(c[x][y]=='1' && c[x][y+1]=='0' && c[x+1][y]=='0' && c[x+1][y+1]=='1'){
    
    
        change1(x,y);change4(x,y);
    }else if(c[x][y]=='0' && c[x][y+1]=='1' && c[x+1][y]=='1' && c[x+1][y+1]=='0'){
    
    
        change2(x,y);change3(x,y);
    }else if(c[x][y]=='0' && c[x][y+1]=='1' && c[x+1][y]=='0' && c[x+1][y+1]=='1'){
    
    
        change1(x,y);change3(x,y);
    }else if(c[x][y]=='0' && c[x][y+1]=='0' && c[x+1][y]=='1' && c[x+1][y+1]=='1'){
    
    
        change1(x,y);change2(x,y);
    }else if(c[x][y]=='1' && c[x][y+1]=='1' && c[x+1][y]=='1' && c[x+1][y+1]=='0'){
    
    
        change1(x,y);
    }else if(c[x][y]=='1' && c[x][y+1]=='1' && c[x+1][y]=='0' && c[x+1][y+1]=='1'){
    
    
        change2(x,y);
    }else if(c[x][y]=='1' && c[x][y+1]=='0' && c[x+1][y]=='1' && c[x+1][y+1]=='1'){
    
    
        change3(x,y);
    }else if(c[x][y]=='0' && c[x][y+1]=='1' && c[x+1][y]=='1' && c[x+1][y+1]=='1'){
    
    
        change4(x,y);
    }else if(c[x][y]=='1' && c[x][y+1]=='1' && c[x+1][y]=='1' && c[x+1][y+1]=='1'){
    
    
        change4(x,y);change1(x,y);change2(x,y);change3(x,y);
    }
}
int main()
{
    
    
    scanf("%d",&t);
    while(t--){
    
    
        vec.clear();
        scanf("%d %d\n",&n,&m);
        for(int i=1;i<=n;i++){
    
    
            scanf("%s",c[i]+1);
        }
        for(int i=1;i<n-1;i++){
    
    
            for(int j=1;j<m;j++){
    
    
                if(c[i][j]=='1'){
    
    
                    if(c[i][j+1]=='1'){
    
    
                        change1(i,j);
                    }else{
    
    
                        change3(i,j);
                    }
                }
            }
            if(c[i][m]=='1'){
    
    
                change4(i,m-1);
            }
        }
        for(int i=1;i<m-1;i++){
    
    
            if(c[n-1][i]=='1'){
    
    
                if(c[n][i]=='1'){
    
    
                    change1(n-1,i);
                }else{
    
    
                    change2(n-1,i);
                }
            }else{
    
    
                if(c[n][i]=='1'){
    
    
                    change4(n-1,i);
                }
            }
        }
        solve(n-1,m-1);
        printf("%d\n",vec.size()/3);
        for(int i=0;i<vec.size();i+=3){
    
    
            printf("%d %d %d %d %d %d\n",vec[i].first,vec[i].second,vec[i+1].first,vec[i+1].second,vec[i+2].first,vec[i+2].second);
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/blaction/article/details/109771621