MemSQL Start[c]UP 2.0 - Round 2
反正晚上睡不着,熬到1点开始做比赛,6个题目只做了2个题目,而且手速还比较慢,待提升空间还很大呢。
A题:给定两个0,1串(len<=100000), 但是不是普通的二进制串,而是q进制串,q = (√5 + 1)/2,比较这两个串的大小。
分析:q的长度很大,即使用大数似乎也不怎么合理,其实我写了半天大数,用最大长度数据测试发现根本出不了结果,也许我写的太挫了,也学时间就耗在上面了。
最终只能另想方法,而且题目中也说明了q^2 = q+1,所以很容易想到利用这个来做这个题, 观察到对于一个串中连续2个1,可以转化为高位的1个1,而且大小不变。这个题目比较大小的难点在于,会存在100 和011相等的情况,也就是不能通过一步步比较最高位来判断大小,低位也会影响。所以关键在于如何消除这种影响,我想到的方法就是从低位开始将连续2个1消去,变成高位1,如00110变成01000就好了,但是有一个问题就是遇到这种情况,001110,不止2个1连着,这样如果将最低2个1消除,会使得高位有2个1,001(2)000,这事就应该将连续一段最后两个1消除。这样做了一次之后还不够,需要反过来在做一次,比如这种情况,01111100,第一遍之后变成10011100,反过来遇到连续2个1,则变成高位,第二遍变成10100100,至于为什么这样做,因为第一遍之后会给后面的连续的1空出至少2个空间,这样第二遍的时候就不会有高位2个1的情况。
具体实现用到了bitset,只是因为最近学到了它,想熟练一下只用。
代码:
//Template updates date: 20140718
#include <bits/stdc++.h>
#define in freopen("solve_in.txt", "r", stdin);
using namespace std; const int maxn = + ;
bitset<maxn> a, b;
void solve(bitset<maxn> &x) {
for(int i = ; i < maxn - ; i++) {
if(x[i] && x[i+] && !x[i+]) {
x[i] = x[i+] =;
x[i+] = ;
i++;
}
}
for(int i = maxn-; i >= ; i--) {
if(x[i] && x[i+]) {
x[i+] = ;
x[i] = x[i+] = ;
}
}
}
int main() { cin>>a>>b;
solve(a);
solve(b);
for(int i = maxn-; i >= ; i--){
if(a[i] > b[i]){
puts(">");
return ;
}
else if(a[i] < b[i]){
puts("<");
return ;
}
}
puts("=");
return ;
}
B题:有2个服务器,每个服务器上分别存储则会2个表,分别有m,n行,其中每个服务器会有很多分区,第一个服务器上第i个分区存储着ai行,第二个服务器第i个分区存储着bi行。
每次操作可以将任何分区上的行复制到其他任何分区,且花费为复制过去的行的数目。求最少的花费,使得对于第1个服务器上表的每行和第2个服务器上的表每个行都至少同时出现在一个分区上。
分析:
先对a[i], b[i]排序,suma[i]表示第一个服务器上前i个分区的行之和,sumb[i]类似。
问题可以这样考虑,第一个服务器上行最终状态是分成了x堆,第二个服务器上行移动到这些堆里面,这里花费为x*sumb[n],第一个服务器的花费应当是,a[i]中最大的x个作为不动分区,其他分区移动到这x个堆上面,花费为suma[x-1],枚举x,去最小值。
同理,可对第二个服务器作为x个堆算出最优值。
代码:
//Template updates date: 20140718
#include <bits/stdc++.h> #define in freopen("solve_in.txt", "r", stdin);
using namespace std;
const int maxn = + ;
double a[maxn], b[maxn], sum1[maxn], sum2[maxn]; int main() { int n, m;
cin>>m>>n;
double ans = 1e25;
for(int i = ; i <= m; i++) {
scanf("%lf", &a[i]);
sum1[i] = sum1[i-]+a[i];
}
for(int i = ; i <= n; i++) {
scanf("%lf", b+i);
sum2[i] = sum2[i-]+b[i];
}
sort(a+, a+m+);
sort(b+, b+n+);
for(int i = ; i <= m; i++) {
sum1[i] = sum1[i-]+a[i];
}
for(int i = ; i <= n; i++) {
sum2[i] = sum2[i-]+b[i];
}
for(int i = ; i <= m; i++) {
double tmp = sum2[n]*i+sum1[m-i];
ans = min(ans, tmp);
}
for(int i = ; i <= n; i++) {
double tmp = sum1[m]*i+sum2[n-i];
ans = min(ans, tmp);
}
printf("%.0f\n", ans);
return ;
}
C题:有n支选票,投给ai,如果要这个人把票投给自己,那么需要花费bi,自己的标号为0。求最少的花费,使得自己选票比选票数目最多的那个人还要多。
分析:研究了半天别人代码,发现大抵方法是这样的:首先统计每个人得到的票数,及花费。然后将每个人票花费从小到大排序,统计出每个人的票数排序。
然后就是枚举我需要得到的票数i了,每次从票数比我多的人中减去一票,如果没有达到i,那么才弄个剩下的票数中选出花费最小的一些票。
更新剩下的票数,并选出最小的一些个时用到了树状数组,看了@JayYe的代码,自己仿写了一遍,我不会这一题啊。自己看了还不是很理解~~GG
另外, 好像还可以用三分?
树状数组实现代码:
值得学习的是, 里面查询最小k个的花费时的函数,二进制位从高到低枚举,每次cnt + num[res] < k ,则说明该高位应该加进去。
#include <bits/stdc++.h>
#define in freopen("solve_in.txt", "r", stdin);
#define lson rt<<1, l, m
#define rson rt<<1|1, m+1, r
#define lowbit(x) ((x)&(-(x)))
using namespace std;
const int maxn = +;
const int maxm = +; map<int, multiset<int> > mps;
typedef map<int, multiset<int> > :: iterator it; int n;
int x[maxn], y[maxn], cost[maxn], pos[maxm], val[maxm], num[maxm];
int sz[maxn], r[maxn];
int cnt, tot;
bool cmp(int a, int b) {
return sz[a] > sz[b];
}
void update(int x, int v) {
int tmp = cost[x];
while(x < maxm) {
num[x] += v;
val[x] += v*tmp;
x += lowbit(x);
}
}
int query1(int x) {
int res = ;
while(x > ) {
res += num[x];
x -= lowbit(x);
}
return res;
}
int query2(int x) {
int res = ;
while(x > ) {
res += val[x];
x -= lowbit(x);
}
return res;
}
int findup(int x) {
int res = ;
int tmp = ;
for(int i = ; i >= ; i--) {
res += (<<i);
if(res >= tot || tmp + num[res] >= x)
res -= (<<i);
else tmp += num[res];
}
return res + ;
}
#define bug puts(">>>>>>>>>>>><<<<<");
int main() { cin>>n;
for(int i = ; i < n; i++) {
scanf("%d%d", x+i, y+i);
if(x[i])
mps[x[i]].insert(y[i]);
}
for(int i = ; i < n; i++) {
cost[++tot] = y[i];
}
sort(cost+, cost+tot+);
tot = unique(cost+, cost+tot+)-cost;
for(int i = ; i < tot; i++) {
pos[cost[i]] = i;
}
for(int i = ; i < n; i++) {
update(pos[y[i]], );
}
for(it s = mps.begin(); s != mps.end(); s++) {
r[cnt++] = s->first;
sz[s->first] = (s->second).size();
}
sort(r, r+cnt, cmp);
int j = ;
int nn = , ans = 0x7f0f0f0f, ccost = ;
for(int i = n; i >= ; i--) {
while(j < cnt && sz[r[j]] >= i) j++;
for(int k = ; k < j; k++) {
nn++;
int tmp = *mps[r[k]].begin();
ccost += tmp;
mps[r[k]].erase(mps[r[k]].begin());
update(pos[tmp], -);
}
int cc = ccost;
int kk = max(i-nn, );
if(kk > ) {
int p = findup(kk);
int t1 = query2(p-);
cc += t1 + (kk-query1(p-))*cost[p];
}
ans = min(ans, cc);
}
printf("%d\n", ans);
return ;
}
MemSQL Start[c]UP 2.0 - Round 2的更多相关文章
- MemSQL Start[c]UP 2.0 - Round 1(无聊练手B题)
http://codeforces.com/contest/452/problem/B B. 4-point polyline time limit per test 2 seconds memo ...
- MemSQL Start[c]UP 2.0 - Round 2 - Online Round
搞到凌晨4点一个没出,要gg了. A. Golden System http://codeforces.com/contest/458/problem/A #include<cstdio> ...
- MemSQL Start[c]UP 2.0 - Round 1
A. Eevee http://codeforces.com/contest/452/problem/A 字符串水题 #include<cstdio> #include<cstrin ...
- MemSQL Start[c]UP 2.0 - Round 1E. Three strings
题意:给3个字符串,问从1到min(l1,l2,l3)的长度的子串,找到从该位置长度为l,三个子串相同的三元组的个数 题解:把3个子串用分隔符串起来.然后分开统计每个节点在三个串中出现次数.最后乘起来 ...
- Codeforces Round #437 (Div. 2, based on MemSQL Start[c]UP 3.0 - Round 2) E
题意:减前面的数,加后面的数,保证最后不剩下数,加减次数要相同: 题解:emmmmm,看出是个贪心,先对价值排序,相同就对下标排序,规律是每次找第一个,然后从后往前找没有使用过的下表比他大的第一个,相 ...
- 【MemSQL Start[c]UP 3.0 - Round 1 E】Desk Disorder
[链接]h在这里写链接 [题意] 有N个人. 2N个座位. 现在告诉你这N个人它们现在的座位.以及它们想去的座位. 每个人可以去它们想去的座位或者就站在原地不动. 新的座位和旧的座位,都不允许一个座位 ...
- 【MemSQL Start[c]UP 3.0 - Round 1 C】 Pie Rules
[链接]h在这里写链接 [题意] 在这里写题意 [题解] dp[i][0] 第i个位置,bob没有决策权 dp[i][1] 第i个位置,bob有决策权 dp[n][0] = 0 ...
- 【MemSQL Start[c]UP 3.0 - Round 1 B】 Lazy Security Guard
[链接]h在这里写链接 [题意] 围成对应面积的方块最少需要多少条边. [题解] 有特定的公式的. 2*ceil(2*根号下(n)); -> 自己找下规律也很简单的. [错的次数] 0 [反思] ...
- 【MemSQL Start[c]UP 3.0 - Round 1 A】 Declined Finalists
[链接]h在这里写链接 [题意] 在这里写题意 [题解] max(最大值-25,0) [错的次数] 0 [反思] 在这了写反思 [代码] #include <bits/stdc++.h> ...
随机推荐
- gluster 安装配置基本指南
基于网络上的多篇文章,做了一些调整. gluster安装 ### Installing Gluster wget -P /etc/yum.repos.d http://download.gluste ...
- 多个html编辑器在同一页面加载
http://127.0.0.1:3750/test.aspx 下载:ckfinder,ckeditor编辑器 <script type="text/javascript" ...
- CSS经典布局-圣杯布局、双飞翼布局
圣杯布局的来历是2006年发在a list part上的这篇文章:In Search of the Holy Grail · An A List Apart Article圣杯是西方表达“渴求之物&q ...
- Android沉浸式状态栏实现
Step1:状态栏与导航栏半透明化 方法一:继承主题特定主题 在Android API 19以上可以使用****.TranslucentDecor***有关的主题,自带相应半透明效果 例如: < ...
- MySQL类型属性Unsigned与ZeroFill
1. Unsigned 就是将数字类型无符号化. int的类型范围是-2147483648~2147483647, int unsigned的类型范围是0~4294967295 Unsigned也可能 ...
- RSA算法使用介绍
http://www.cnblogs.com/AloneSword/p/3326750.html RSA是目前最有影响力的公钥加密算法,该算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那 ...
- 第三篇、C_双向链表(循环链表)
简介: 在用C/C++开发系统中,我们知道用数组或者单链表来开发,如果是数据比较大的话,性能很不好,效率也不高.因此常常需要考虑系统的实用性,常常采用双向链表来开发. 示例: 1.数据 typedef ...
- 12天学好C语言——记录我的C语言学习之路(Day 12)
12天学好C语言--记录我的C语言学习之路 Day 12: 进入最后一天的学习,用这样一个程序来综合考量指针和字符串的关系,写完这个程序,你对字符串和指针的理解应该就不错了. //输入一个字符串,内有 ...
- string和stringbuilder
1)String是一个引用类型,一旦字符串被创建,就不能修改 例如: String a="AAA"; String b=a; a与b值相同,但不是同一个对象: 每次使用 Syste ...
- oninput和onpropertychange
时常会有监听输入框输入的场景,比如新浪微博的发微博输入框: 还有边输入边提示: 以及form表单边输入边验证,当内容为空提示或者改变输入框的样式达到提示效果. 在IE中是onpropertychang ...