Room and Moor
Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 263 Accepted Submission(s): 73
Problem Description
PM Room defines a sequence A = {A1, A2,..., AN}, each of which is either 0 or 1. In order to beat him, programmer Moor has to construct another sequence B = {B1, B2,... , BN} of the same length, which satisfies that:
Input
The input consists of multiple test cases. The number of test cases T(T<=100) occurs in the first line of input.
For each test case:
The first line contains a single integer N (1<=N<=100000), which denotes the length of A and B.
The second line consists of N integers, where the ith denotes Ai.
Output
Output the minimal f (A, B) when B is optimal and round it to 6 decimals.
Sample Input
4
9
1 1 1 1 1 0 0 1 1
9
1 1 0 0 1 1 1 1 1
4
0 0 1 1
4
0 1 1 1
Sample Output
1.428571
1.000000
0.000000
0.000000
Source
Recommend
题意:很容易就读懂了。
题解:首先去掉前导零和最后的1,相当于把整个序列分成几个区间,每部分以1开头,0结尾,即如1 0 1 1 0 0等,可知对于每一个区间,要取得最小值,那这个部分所有的值即对应的这个区间内的平均数,如果这个平均数和前面一个区间的相比较大,就压入栈,否则将栈里的元素顶出,并与当前区间合并求平均数……知道比前面的大为止,最后求出每个区间的对应的Seg(ai - bi)^2 就可以了。至于为什么。。。。说实话全是YY,居然A掉了。。
AC代码如下:
#include <cstdio>
#include <cstring>
#include <stack>
using namespace std; #define eps 0.00000001
const int LEN = ; int arr[LEN];
struct line
{
int l, r, sum;
double rate;
}; stack<line> s; int main()
{
int T, n;
line tmp;
scanf("%d", &T);
while(T--){
scanf("%d", &n);
for(int i = ; i < n; i++)
scanf("%d", arr+i);
int h = ;
while(arr[h] == )
h++;
int k = n - ;
while(arr[k] == )
k--;
for(int i = h; i <= k; i++){
if (i == h || i > h && arr[i-] == && arr[i] == ){
tmp.l = i;
tmp.sum = ;
}
if (i < k && arr[i] == && arr[i+] == || i == k){
tmp.r = i;
//printf("l = %d, r = %d\n", tmp.l, tmp.r);
tmp.rate = tmp.sum * 1.0 / ((tmp.r - tmp.l + ) * 1.0);
//printf("rate=%f\n", tmp.rate);
while(true){
if (s.empty() || s.top().rate - tmp.rate < eps){
s.push(tmp);
break;
}
if (s.top().rate - tmp.rate > eps){
tmp.l = s.top().l;
tmp.sum += s.top().sum;
tmp.rate = tmp.sum*1.0 / ((tmp.r - tmp.l + )*1.0);
s.pop();
}
}
}
if (arr[i] == )
tmp.sum++;
}
double ans = ;
while(!s.empty()){
ans += (( - s.top().rate) * ( - s.top().rate) * s.top().sum + s.top().rate * s.top().rate * (s.top().r - s.top().l + - s.top().sum));
s.pop();
}
printf("%f\n", ans);
}
return ;
}