poj3276_翻转问题

来源:互联网 发布:网络赌托该不该举报 编辑:程序博客网 时间:2024/06/06 04:16
#include<iostream>#include<string>using namespace std;const int maxn = 5007;bool D[maxn];bool B[maxn];//B[i]表示第i个格子有没有翻转int main(){    int n;    ios::sync_with_stdio(false);    cin >> n;    string s;    for (int i = 0; i<n; i++)    {        cin >> s;        if (s[0] == 'B')        {            D[i] = 1;        }        else        {            D[i] = 0;        }    }    //方法穷举所有的k,统计每个k的最小翻转次数    int ans = n;    int ansk = -1;    for (int i = 1; i <= n; i++)    {        /*首先同一个开始位置翻转两次是没有意义的        有如下先检查最左边的,如果要反转,那必须进行,从这一个格子的连续k个的翻转        如果不必翻转那么必定不进行从这个格子开始的连续k个的翻转        以此向后推        */        int cnt = 0;        int c = 0;//统计j前面连续不大于i的翻转次数情况        bool flag = true;        for (int j = 0; j<n; j++)        {            if (j + i <= n && (D[j] + c) % 2)//如果能翻转且要翻转,则翻转            {                B[j] = 1;                cnt++;            }            else             {                B[j] = 0;            }            if ((D[j] + c + B[j]) % 2)//检测当前格子是否翻转成正向了,因为后面的操作无法翻转这一个格子了            {                flag = false;                break;            }            c += B[j];//为下一位的检测跟新前面的翻转情况,类似于尺取法            if (j + 1 >= i)            {                c -= B[j + 1 - i];            }        }        if (flag&&ans>cnt)        {            ans = cnt;            ansk = i;        }    }    cout << ansk <<" "<< ans << endl;    return 0;}
0 0
原创粉丝点击