hdu5073 简单枚举+精度处理
其实这题还是挺简单的,因为移动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 简单枚举+精度处理的更多相关文章
- UVA - 10167 - Birthday Cake (简单枚举)
思路:简单枚举 AC代码: #include <cstdio> #include <cstring> #include <iostream> #include &l ...
- Java练习 SDUT-1959_简单枚举类型——植物与颜色
简单枚举类型--植物与颜色 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 请定义具有red, orange, yell ...
- zoj 3356 Football Gambling II【枚举+精度问题】
题目: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3356 http://acm.hust.edu.cn/vjudge/ ...
- zoj 1622 Switch 开关灯 简单枚举
ZOJ Problem Set - 1622 Switch Time Limit: 2 Seconds Memory Limit: 65536 KB There are N lights i ...
- UVa 725 简单枚举+整数转换为字符串
Division Write a program that finds and displays all pairs of 5-digit numbers that between them use ...
- UVA 725 UVA 10976 简单枚举
UVA 725 题意:0~9十个数组成两个5位数(或0开头的四位数),要求两数之商等于输入的数据n.abcde/fghij=n. 思路:暴力枚举,枚举fghij的情况算出abcde判断是否符合题目条件 ...
- 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 ...
- hdu5258简单枚举
百度之星复赛第一题.不明白这么水的题为何一堆人没过...这些人是咋晋级复赛的呢... /* * Author : ben */ #include <cstdio> #include < ...
- C#枚举的简单使用
枚举这个名词大家都听过,很多小伙伴也使用过, 那么枚举在开发中能做什么,使用它后能给程序代码带来什么改变,为什么用枚举. 各位看官且坐下,听我一一道来. 为什么使用枚举? 1.枚举能够使代码更加清晰, ...
随机推荐
- hdu1233
http://acm.hdu.edu.cn/showproblem.php?pid=1233 最小生成树,kruskal算法 #include<stdio.h> #include<m ...
- floodlight StaticFlowPusher 基于网段写flow,通配
flow1 = { "switch":"00:00:00:00:00:00:00:03", "name":"flow-mod-1& ...
- MIT算法导论——第四讲.Quicksort
本栏目(Algorithms)下MIT算法导论专题是个人对网易公开课MIT算法导论的学习心得与笔记.所有内容均来自MIT公开课Introduction to Algorithms中Charles E. ...
- Hibernate逍遥游记-第5章映射一对多-02双向(<set>、<key>、<one-to-many>、inverse、cascade="all-delete-orphan")
1. <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hi ...
- React-用ImmutableJS提高性能
一.需求 1.子组件有更新时,只重新渲染有变化的子组件,而不是全部 二.ImmutableJS原理 三.代码 1.CheckboxWithLabel.jsx var React = require(' ...
- Android Studio 初探
前言 上周由于写了一篇关于"Eclipse+ADT+Android SDK 搭建安卓开发环境" 的博文,其他博主们表示相当的不悦,都什么年代了还用Eclipse+ADT开发安卓应用 ...
- Apache编译与安装 RedHat enterprises 6.2
引自:http://blog.chinaunix.net/uid-26881541-id-3336614.html http://apr.apache.org/download.cgi 命令: yum ...
- Android 清除canvas 笔迹代码
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); canvas.drawLine(pointX, , event.getX(), ...
- highcharts 结合phantomjs纯后台生成图片系列二之php
上篇文章中介绍了phantomjs的使用场景,方法.本篇文章详细介绍使用php,highcharts 结合phantomjs纯后台生成图片. 一.准备: 下载phantomjs解析插件,从 highc ...
- OpenCV码源笔记——RandomTrees (一)
OpenCV2.3中Random Trees(R.T.)的继承结构: API: CvRTParams 定义R.T.训练用参数,CvDTreeParams的扩展子类,但并不用到CvDTreeParams ...