zoukankan      html  css  js  c++  java
  • POJ 3276 Face The Right Way 反转

    大致题意:有n头牛,有些牛朝正面,有些牛朝背面。现在你能一次性反转k头牛(区间[i,i+k-1]),求使所有的牛都朝前的最小的反转次数,以及此时最小的k值。

    首先,区间反转的顺序对结果没有影响,并且,同一区间无需进行多次反转。我们首先从最左边的开始,最左边的牛如果朝前,则不需要反转,用f[i]=0记录下来;反之则反转,f[i]=1.如果最左边的朝向为前,整个序列就可以减少1,依次递推下去。

    当然,有些k值也可能不能完全反转,比如 1 0 1 ,当k=3时,是不可能反转完成的。

    还有既然是区间反转,自然会影响之后的牛是否反转,此时用sum进行记录,判断sum+牛的方向 是否为奇数。

    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int maxn = 5000 + 10;
    
    int n;
    char s[maxn];
    int dir[maxn];
    int f[maxn];     //区间[i, i + k - 1]是否进行反转
    
    int calculate_m(int k)
    {
        int sum=0;
        int ret=0;
        memset(f,0,sizeof(f));
        for(int i=0;i<=n-k;i++)
        {
            if((dir[i]+sum)%2)
            {
                ret++;
                f[i]=1;
                sum+=f[i];
            }
            if(i-k+1>=0) // 减去不影响的反转次数
                sum-=f[i-k+1];
        }
        for(int i=n-k+1;i<n;i++) //判断剩余的区间
        {
            if((dir[i]+sum)%2)
                return -1;
            if(i-k+1>=0)
                sum-=f[i-k+1];
        }
        return ret;
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            getchar();
            int c=getchar();
            if(c=='F')
                dir[i]=0;
            else
                dir[i]=1;
        }
        int ans_k=1,ans_m=n;
        for(int i=1;i<=n;i++)
        {
            int m=calculate_m(i);
            if(m>=0 && m<ans_m)
            {
                ans_k=i;
                ans_m=m;
            }
        }
        printf("%d %d
    ",ans_k,ans_m);
        return 0;
    }
  • 相关阅读:
    iOS 静态、全局变量、常量
    原子性atomic/nonatomic
    iOS数组遍历
    iOS开发过程中易犯的小错误
    mac开启Airdrop的硬件要求
    Activity Monitor 闪退 & 无法进入睡眠
    在Linux中连接android设备
    网格布局(GridLayout) 行数与列数
    $符号报not defing 报错
    eclipse鼠标变成十字符号
  • 原文地址:https://www.cnblogs.com/pach/p/6017520.html
Copyright © 2011-2022 走看看