• Face The Right Way [POJ3276] [开关问题]


    题意:

    有n头奶牛排成一排,有的朝前(F)有的朝后(B),现在你可以使k头奶牛一次性翻转朝向(n>=k>=1),问你最少的翻转次数和此时对应的k值。 

    Input

    Line 1: A single integer: N 
    Lines 2.. N+1: Line i+1 contains a single character, F or B, indicating whether cow i is facing forward or backward.

    Output

    Line 1: Two space-separated integers: K and M

    Sample Input

    7
    B
    B
    F
    B
    F
    B
    B

    Sample Output

    3 3

    Analysis

    我们先来观察,可以发现,处理好i前面的点后,如果i这个点是B的话,就必须反向,而反向一次以上的话,是无效的(奇数次与1次等效,偶数次于0次等效)。

    所以我们可以枚举K,然后从1处理到N,如果需要处理,就再套一个循环修改。这样的复杂度是O(N3),仍然不够。

    我们想,如果这个数加上[i-k+1,i-1]的翻转次数,是奇数的话就代表需要切换,然后记录下区间次数和sum每次加上新处理的点,去掉即将在区间外的点。这样,就降到N2

    Code

     1 #include<set>
     2 #include<map>
     3 #include<queue>
     4 #include<stack>
     5 #include<cmath>
     6 #include<cstdio>
     7 #include<cstring>
     8 #include<iostream>
     9 #include<algorithm>
    10 #define RG register int
    11 #define rep(i,a,b)    for(RG i=a;i<=b;++i)
    12 #define per(i,a,b)    for(RG i=a;i>=b;--i)
    13 #define ll long long
    14 #define inf (1<<29)
    15 #define maxn 5005
    16 using namespace std;
    17 int n,ans1=inf,ans2;
    18 int num[maxn],f[maxn];
    19 char s[5];
    20 inline int read()
    21 {
    22     int x=0,f=1;char c=getchar();
    23     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    24     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    25     return x*f;
    26 }
    27 
    28 int main()
    29 {
    30     n=read();
    31     rep(i,1,n)    {scanf("%s",s);if(s[0]=='B')    num[i]=1;}
    32     rep(k,1,n)
    33     {    
    34         int sum=0,cnt=0;memset(f,0,sizeof(f));
    35         for(RG i=1,lim=n-k+1;i<=lim;++i)
    36         {
    37             if((num[i]+sum)&1)    f[i]=1,cnt++;
    38             sum+=f[i];if(i-k>=0)sum-=f[i-k+1];
    39         }
    40         rep(i,n-k+2,n)
    41         {
    42             if((num[i]+sum)&1)    
    43             {
    44                 cnt=-1;break;
    45             }
    46             sum+=f[i];if(i-k>=0)sum-=f[i-k+1];
    47         }
    48         if(cnt==-1)        continue;
    49         if(cnt<ans1)    ans1=cnt,ans2=k;
    50     }
    51     cout<<ans2<<" "<<ans1;
    52     return 0;
    53 }
    View Code
  • 相关阅读:
    element ui 表单清空
    element ui 覆盖样式 方法
    element ui 修改表单值 提交无效
    element ui 抽屉里的表单输入框无法修改值
    element ui 抽屉首次显示 闪烁
    css 左侧高度 跟随右侧内容高度 自适应
    PICNUF框架
    elementui 抽屉组件标题 出现黑色边框
    vue 子组件跨多层调用父组件中方法
    vue 编辑table 数据 未点击提交,table里的数据就发生了改变(深拷贝处理)
  • 原文地址:https://www.cnblogs.com/ibilllee/p/9290422.html
Copyright © 2020-2023  润新知