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.枚举能够使代码更加清晰, ...
随机推荐
- 欧拉工程第60题:Prime pair sets
题目链接 五个数,任意两个数的任意链接后的数还是质数 满足这个条件的最小五个数的和是多少? 结果:26033 纯暴力破解: package projecteuler51to60; import jav ...
- 转贴: A Simple c# Wrapper for ffMpeg
原帖地址:http://jasonjano.wordpress.com/2010/02/09/a-simple-c-wrapper-for-ffmpeg/ A Simple c# Wrapper fo ...
- Apache与Tomcat整合
Apache与Tomcat整合 一 Apache与Tomcat比较联系 apache支持静态页,tomcat支持动态的,比如servlet等. 一般使用apache+tomcat的话,apache ...
- python 解析 xml
<taskList nextId="62292"> <task module="reliability" owner="vprovo ...
- 被称为同步神器的 BTSync,你可以怎么用?
在这高速运作的信息化时代,使用云端来衔接工作和生活的点滴已是寻常事.可你是否曾扪心自问过:用各大云端备份自己的信息资料,真的安全放心吗? 毫不夸张的说,其实恶意代码和漏洞早已和你如影随形.你甚至都不用 ...
- [iOS]iPhone利用<极光推送>实现远程推送
准备: 1. 一个Xcode工程 2. 开发者账号 3. 真机 (重要,模拟器无法进行远程推送,因为模拟器没有UDID) 第一步:绑定工程的Bundle Identifer 首先当然要登录https: ...
- Quartz 并发/单线程
Quartz 并发/单线程 Quartz定时任务默认都是并发执行的,不会等待上一次任务执行完毕,只要间隔时间到就会执行, 如果定时任执行太长,会长时间占用资源,导致其它任务堵塞.1.在Spring中这 ...
- 72. Edit Distance
题目: Given two words word1 and word2, find the minimum number of steps required to convert word1 to w ...
- 1、Web容器的理解&Tomcat的安装与配置
Web容器的理解 <Java Web开发实战经典——基础篇>一书中对Web容器这一概念阐述得很好,借用其观点对Web容器加以理解: 想要运行一个Java Web的程序,则必须有相应的Web ...
- linux源码Makefile详解
1.Makefile的作用 (1)决定编译哪些文件 (2)怎样编译这些文件 (3)怎样连接这些文件,最重要的是它们的顺序如何 2.Linux内核Makefile分类 ***************** ...