1704: [Usaco2007 Mar]Face The Right Way 自动转身机
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 457 Solved: 276
[ Submit][ Status][ Discuss]
Description
农夫约翰有N(1≤N≤5000)只牛站成一排,有一些很乖的牛朝前站着.但是有些不乖的牛却朝后站着.农夫约翰需要让所有的牛都朝前站着.幸运的是约翰最近买了一个自动转身机.这个神奇的机器能使K(1≤K≤N)只连续的牛转身. 因为约翰从来都不改变K的价值,请帮助他求出K,使旋转次数M达到最小.同时要求出对应的M.
Input
第1行:整数N.
第2行到第N+1行:第i+l行表示牛j的朝向,F表示朝前,B表示朝后.
Output
一行两个数,分别是K和M,中间用空格隔开
Sample Input
7
B
B
F
B
F
B
B
Sample Output
3 3
可以将原题转化为:一个长度为n的01串,每次可以将连续k个数字翻转,
问当k等于多少时,将串翻为全0所需翻转次数最少
暴力k的大小,然后贪心判断能否全部转过来。
从左向右每次找到一个没翻转的,就把从它开始连续的k个转过来,如果不够k个,说明无法翻转
#include<stdio.h>
#include<string.h>
int a[5005], f[5005];
int main(void)
{
char ch;
int n, i, k, sum, rev, ans, temp;
while(scanf("%d", &n)!=EOF)
{
for(i=1;i<=n;i++)
{
scanf(" %c", &ch);
if(ch=='B') a[i] = 1;
else a[i] = 0;
}
ans = n;
for(k=1;k<=n;k++)
{
sum = rev = 0;
memset(f, 0, sizeof(f));
for(i=1;i<=n-k+1;i++)
{
if((a[i]^rev)==1)
{
sum++;
rev ^= 1;
f[i+k-1] = 1;
}
rev ^= f[i];
}
for(;i<=n;i++)
{
if((a[i]^rev)==1)
break;
rev ^= f[i];
}
if(i<=n)
continue;
if(sum<ans)
ans = sum, temp = k;
}
printf("%d %d\n", temp, ans);
}
return 0;
}