Codeforces Round #684 (Div. 2)

58 篇文章 0 订阅
35 篇文章 1 订阅

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(){
    // prework();
    // test();
    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 ++;
        }
//        cout<<cnt0<<" "<<cnt1<<endl;
//        cout<<c0<<" "<<c1<<" "<<h<<endl;
        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<<cnt0*c0+(c0+h)*cnt1<<" "<<cnt1*c1 + (c1+h)*cnt0<<endl;
        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(){
    // prework();
    // test();
    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;
//int a[N],b[N],c[N];
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){
    //cout<<x<<" --- "<<y<<endl;
    int tmp = count(x,y);
//    cout<<tmp<<endl;
//    cout<<endl;
    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(){
    // prework();
    // test();
    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矩阵了。然后枚举所有22矩阵。不要重复枚举就行了。

比赛的时候想歪了。我想的是用操作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;
//int a[N],b[N],c[N];
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(){
    // prework();
    // test();
    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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值