其实这题还是挺简单的,因为移动k个星球后,这k个星球的权值就可以变为0,所以只有剩下的本来就是连着的才是最优解,也就是说要动也是动两端的,那么就O(N)枚举一遍动哪些就好了。

我是在杭电oj题目重现的比赛上做这题,因为之前听人说现场赛时有人用n^2的算法蹭过了,所以我不断蹭,蹭了一个小时都没蹭过。。。~!@#¥%……

先贴一份乱七八糟想蹭过的代码

/*
* Author : ben
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#include <stack>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <functional>
#include <numeric>
#include <cctype>
using namespace std;
typedef long long LL;
const double eps = 1e-;
int get_int() {
int res = , ch;
while (!((ch = getchar()) >= '' && ch <= '')) {
if (ch == EOF)
return << ;
}
res = ch - '';
while ((ch = getchar()) >= '' && ch <= '')
res = res * + (ch - '');
return res;
}
//输入整数(包括负整数),用法int a = get_int2();
int get_int2() {
int res = , ch, flag = ;
while (!((ch = getchar()) >= '' && ch <= '')) {
if (ch == '-')
flag = ;
if (ch == EOF)
return << ;
}
res = ch - '';
while ((ch = getchar()) >= '' && ch <= '')
res = res * + (ch - '');
if (flag == )
res = -res;
return res;
}
const int MAXN = ;
int N, K, data[MAXN];
int ndata[MAXN];
LL sum[MAXN];
double ans; inline double getCenter(int s, int e) {
LL su = sum[e];
if (s > ) {
su -= sum[s - ];
}
double ret = su / (e - s + 1.0);
return ret;
} void comput(int s, int e, double c) {
double ret = ;
for (int i = s; i <= e; i++) {
ret += (data[i] - c) * (data[i] - c);
if (ret > ans) {
return;
}
}
if (ret < ans) {
ans = ret;
}
} double comput(double c) {
double ret = ;
for (int i = ; i < N; ) {
ret += (data[i] - c) * (data[i] - c) * ndata[i];
i += ndata[i];
}
return ret;
} void work() {
double cen = getCenter(, N - );
// printf("cen = %f\n", cen);
ans = comput(cen);
for (int a = K; a >= ; a--) {
if (ans < eps) {
break;
}
int e = N + a - K - ;
double tmpc = getCenter(a, e);
comput(a, e, tmpc);
}
} void treat() {
for (int i = ; i < N; i++) {
int d = data[i];
int j = i + ;
while (j < N && data[j] == d) {
j++;
}
int num = j - i;
for (j--; j >= i; j--) {
ndata[j] = num - j + i;
}
}
} int main() {
int T = get_int();
while (T--) {
N = get_int();
K = get_int();
for (int i = ; i < N; i++) {
data[i] = get_int2();
}
sort(data, data + N);
treat();
sum[] = data[];
for (int i = ; i < N; i++) {
sum[i] = sum[i - ] + data[i];
}
work();
printf("%.10lf\n", ans);
}
return ;
}

下面是正常做法,其实相对于上面的代码也就只有一处改进,因为上面那份代码求解(xi-x)^2的时候是依次计算累加的,可以通过展开公式,通过预存前n项平方和的方式来计算,把这个计算过程从O(N)变成O(1),就可以过了。

不过我还是wa了几发,原因是一开始忘了对N==K和N-1==K的情况作特殊处理了,因为我后面的代码这个地方没单独考虑。

 /*
* Author : ben
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#include <stack>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <functional>
#include <cctype>
using namespace std;
typedef long long LL;
const double eps = 1e-;
const int MAXN = ;
int N, K;
LL data[MAXN], sum[MAXN], sum2[MAXN];
double ans;
int get_int() {
int res = , ch;
while (!((ch = getchar()) >= '' && ch <= '')) {
if (ch == EOF)
return << ;
}
res = ch - '';
while ((ch = getchar()) >= '' && ch <= '')
res = res * + (ch - '');
return res;
} //输入整数(包括负整数),用法int a = get_int2();
int get_int2() {
int res = , ch, flag = ;
while (!((ch = getchar()) >= '' && ch <= '')) {
if (ch == '-')
flag = ;
if (ch == EOF)
return << ;
}
res = ch - '';
while ((ch = getchar()) >= '' && ch <= '')
res = res * + (ch - '');
if (flag == )
res = -res;
return res;
}
inline LL getSum(int from, int to) {
LL ret = sum[to];
if (from > ) {
ret -= sum[from - ];
}
return ret;
} inline LL getSum2(int from, int to) {
LL ret = sum2[to];
if (from > ) {
ret -= sum2[from - ];
}
return ret;
} inline double getCenter(int s, int e) {
LL su = sum[e];
if (s > ) {
su -= sum[s - ];
}
double ret = su / (e - s + 1.0);
return ret;
} inline double comput(int s, int e, double c) {
LL s1 = getSum(s, e);
LL s2 = getSum2(s, e);
double ret = s2 + (e - s + 1.0) * c * c - 2.0 * c * s1;
return ret;
} void work() {
double cen = getCenter(, N - );
ans = comput(, N - , cen);
for (int a = ; a <= K; a++) {
int e = N + a - K - ;
double tmpc = getCenter(a, e);
double ret = comput(a, e, tmpc);
if (ret < ans) {
ans = ret;
}
}
} int main() {
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
#endif
int T= get_int();
while (T--) {
N = get_int();
K = get_int();
for (int i = ; i < N; i++) {
data[i] = get_int2();
}
if (K == N || N - == K) {
printf("0\n");
continue;
}
sort(data, data + N);
sum[] = data[];
sum2[] = data[] * data[];
for (int i = ; i < N; i++) {
sum[i] = sum[i - ] + data[i];
sum2[i] = sum2[i - ] + data[i] * data[i];
}
work();
printf("%.10lf\n", ans);
}
return ;
}

hdu5073 简单枚举+精度处理的更多相关文章

  1. UVA - 10167 - Birthday Cake (简单枚举)

    思路:简单枚举 AC代码: #include <cstdio> #include <cstring> #include <iostream> #include &l ...

  2. Java练习 SDUT-1959_简单枚举类型——植物与颜色

    简单枚举类型--植物与颜色 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 请定义具有red, orange, yell ...

  3. zoj 3356 Football Gambling II【枚举+精度问题】

    题目: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3356 http://acm.hust.edu.cn/vjudge/ ...

  4. zoj 1622 Switch 开关灯 简单枚举

    ZOJ Problem Set - 1622 Switch Time Limit: 2 Seconds      Memory Limit: 65536 KB There are N lights i ...

  5. UVa 725 简单枚举+整数转换为字符串

    Division  Write a program that finds and displays all pairs of 5-digit numbers that between them use ...

  6. UVA 725 UVA 10976 简单枚举

    UVA 725 题意:0~9十个数组成两个5位数(或0开头的四位数),要求两数之商等于输入的数据n.abcde/fghij=n. 思路:暴力枚举,枚举fghij的情况算出abcde判断是否符合题目条件 ...

  7. uva 10976 Fractions Again(简单枚举)

    10976 Fractions Again It is easy to see that for every fraction in the form 1 k (k > 0), we can a ...

  8. hdu5258简单枚举

    百度之星复赛第一题.不明白这么水的题为何一堆人没过...这些人是咋晋级复赛的呢... /* * Author : ben */ #include <cstdio> #include < ...

  9. C#枚举的简单使用

    枚举这个名词大家都听过,很多小伙伴也使用过, 那么枚举在开发中能做什么,使用它后能给程序代码带来什么改变,为什么用枚举. 各位看官且坐下,听我一一道来. 为什么使用枚举? 1.枚举能够使代码更加清晰, ...

随机推荐

  1. 套题T5//各种树

    树(tree) [题目描述] 方方方种下了三棵树,一年后,第一棵树长出了n个节点. 方方方会向你提出m个询问,每个询问给出两个数i,j,你需要回答i号节点和j号节点在树上的距离. [输入数据] 第一行 ...

  2. 李洪强iOS开发之上传照片时英文改中文

    今天在做项目的时候,有一个功能是上传照片选择系统相册的照片,或者拍照上传照片,但是页面上的文字是英文的, 需求想改成中文的,解决方法是在 info.plist里面添加 Localized resour ...

  3. LR_问题_脚本运行时提示没有参数化

    问题描述 将loadrunner中的参数删除,并且删除脚本目录下对应的bak,执行脚本,出现下面的错误: “错误: 表“XX\phonenumbser.dat”不存在.         [MsgId: ...

  4. MyEclipse 利用反向功能生成Java 实体类

    1.Window -> Open Perspective -> MyEclipse Database Explorer 到DB Broswer界面 2.右键 -> New,新建一个数 ...

  5. 深度卷积神经网络用于图像缩放Image Scaling using Deep Convolutional Neural Networks

    This past summer I interned at Flipboard in Palo Alto, California. I worked on machine learning base ...

  6. QTP鼠标点击和浏览器事件的动态切换

    今天在群里有人问到一个问题,我觉得应该会有很多人会碰到,今天根据自己的思路把这个解决方案整理出来,供自己和大家参考 需求描述: 当输入一个身份证号码的时候,这个号码所对应的数据会被加载到所属的省和市的 ...

  7. PHP程序员最常犯的11个MySQL错误

    对于大多数web应用来说,数据库都是一个十分基础性的部分.如果你在使用PHP,那么你很可能也在使用MySQL—LAMP系列中举足轻重的一份子. 对于很多新手们来说,使用PHP可以在短短几个小时之内轻松 ...

  8. linux系统的文件类型学习

    linux是一个文件型操作系统,在linux下一切皆文件. 目录.字符设备.块设备.管道.套接字.符号连接文件等在linux下统统都是文件. linux下的文件类型分为以下几种类型: 1. 正规文件, ...

  9. vs2012 arcgis engine 10 丢失arcgis模板

    1.Visual Studio 2012环境下安装ArcGIS Engine 10 Visual Studio 2012环境下安装ArcObject SDK for the Microsoft .Ne ...

  10. 04-语言入门-04-Fibonacci数

    地址: http://acm.nyist.net/JudgeOnline/problem.php?pid=13    描述 无穷数列1,1,2,3,5,8,13,21,34,55...称为Fibona ...