zoukankan      html  css  js  c++  java
  • USACO07 MAR Face The Right Way G

    疫情当下,美帝又开始倒牛奶了,这一幕似曾相识啊~~~

    这个题目非常的应景,又是美国佬的奶牛

    【题目地址】

    【一句话题意】

    N头牛排成一列1<=N<=5000。每头牛或者向前或者向后。
    为了让所有牛都 面向前方,农夫每次可以将K头连续的牛转向1<=K<=N,
    求操作的最少次数M和对应的最小K。

    【Input】

    第1行:单个整数:N
    第2..N + 1行:第i + 1行包含单个字符F或B,指示母牛i面向前还是面向后。

    【Output】

    第1行:两个以空格分隔的整数:K和M

    【Sample】

    input
    7
    B
    B
    F
    B
    F
    B
    B
    
    output
    3 3
    

    【分析&思路】

    区间修改?
    线段树、树状数组,暴力枚举01修改——boom
    我们注意到每一个点只有两种状态0|1
    那么如果修改两次的话就相当于没改咯
    我们把区间分开考虑
    怎么说
    就是把最左边连续的一段进行操作变为全部向前
    于是在后续的操作中我们duck不必再考虑前面的
    这思路没啥问题,直接上暴力

    #include <cstdio>
    using namespace std;
    int n, a[5005][5005], minn = 99999, step , pin;
    
    int main(){
        scanf("%d",&n);
        for(int i = 1; i <= n; i++){
            char ch;
            getchar();
            ch = getchar();
            if(ch == 'B') a[0][i] = 0;
            else a[0][i] = 1;
        }
        for(int i = 1; i <= n; i++){
            step = 0;
            int flag = 0;
            for(int j = 1; j <= n; j++)
            a[i][j] = a[0][j];
            for(int j = 1; j <= n - i + 1; j++){
                if(!a[i][j]){
                for(int k = 0; k < i ; k++){
                    a[i][j + k] ^= 1;
                }
                step++;
                if(step > minn) break;
                }
            }
            for(int j = n - i + 2; j <= n; j++){
                if(!a[i][j]){
                    flag = 1;
                    break;
                }
            }
            for(int j = 1; j <= n; j++)
            if(!flag) {
                if(minn > step)
                {
                    minn = step;
                    pin = i;
                }
            }
        }
        printf("%d %d", pin, minn);
        return 0;
    } 
    

    然后……T掉了……
    那么我们再来考虑优化的方法
    类似于差分
    在此,可能叫做“异或分”
    记录区间长度为k
    每次反转的时候更改标记为0或1
    给两个区间分别异或
    则不改变前后区间的相对状态
    总的时间复杂度为(O(n^2))
    emmmmm就这样叭
    代码非原创

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn = 10009;
    int n;
    bool A[maxn],B[maxn];
    int main(){
        scanf("%d",&n);
        char ch;
        for(int i=1;i<=n;++i){
            cin>>ch;A[i]=ch=='B'?0:1;
        }
        int mincnt=0x7fffffff,anslen;
        for(int len=1;len<=n;++len){
            memset(B,0,sizeof B);
            bool b=0,flag=1;int cnt=0;//flag记录当前长度是否有解
            for(int i=1;i<=n;++i){//因为区间翻转只有状态0和1,所以用^代替+和-
                b^=B[i];//数组B为记录差分的数组
                if(!(A[i]^b)){//若当前位置为0
                    if(i+len-1>n){flag=0;break;}//唯一的失败条件:一次翻转的长度大于剩余的长度
                    b^=1,B[i+len]^=1;
                    ++cnt;
                }
            }
            if(flag){if(cnt<mincnt)mincnt=cnt,anslen=len;}
        }printf("%d %d
    ",anslen, mincnt);
    } 
    
    风吹过,我来过~
  • 相关阅读:
    git(1)-git关联GitHub-windows-转载
    jenkins(4)-jenkins配置邮件通知
    jenkins(3)-linux下安装jenkins(yum install方式)
    【PAT甲级】1090 Highest Price in Supply Chain (25 分)(DFS)
    【PAT甲级】1087 All Roads Lead to Rome (30 分)(MAP【int,string】,邻接表,DFS,模拟,SPFA)
    【PAT甲级】1018 Public Bike Management (30 分)(DFS,SPFA)
    Educational Codeforces Round 61 (Rated for Div. 2) G(线段树,单调栈)
    Atcoder Grand Contest 032C(欧拉回路,DFS判环)
    Educational Codeforces Round 62 (Rated for Div. 2)E(染色DP,构造,思维,组合数学)
    Atcoder Grand Contest 031C(构造,思维,异或,DFS)
  • 原文地址:https://www.cnblogs.com/rui-4825/p/12642272.html
Copyright © 2011-2022 走看看