codeforece Round#311 BCDE
B题
给我们n,m , m表示茶壶的容量
接下来2*n个数字,表示茶杯的容量,将这些茶杯分给n个男孩和n个女孩
可以倒x毫升的茶水给每个女孩,那么就要倒2x毫升的茶水给男孩,当然了,茶杯要装的下,且茶壶的水足够多
问最多能倒多少毫升?
思路:将茶杯按容量从下到大排序,那么前n个茶杯一定分给女孩,后n个茶杯分给男孩。那么只要将第一个茶杯的容量作为上界,0作为下界,二分枚举x,
每次统计后n个茶杯的容量是不是>=2x,如果是,那么说明该容量是可行的。 但是最终的数据测试却错了, 因为精度要达到1e-11才能正确,不知道为什么
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <math.h>
using namespace std;
#pragma warning(disable:4996)
typedef long long LL;
const int INF = <<;
const double eps = 1e-;
/* */
int a[ + ];
int main()
{
int n, w;
while (scanf("%d%d", &n,&w) != EOF)
{
int m = * n;
for (int i = ; i < m; ++i)
{
scanf("%d", &a[i]);
}
sort(a, a + m);
double low = , high = a[], mid;
int cnt;
double tmp;
while (high - low >= eps)
{
mid = (high + low) / ;
cnt = ;
for (int i = ; i < m; ++i)
if (mid * <= a[i])
cnt++;
if (cnt >= n)
{
tmp = mid * * n;
if (tmp<w)
high = mid;
else
low = mid;
}
else
high = mid;
}
printf("%f\n", mid * * n); }
return ;
}
比完看了别人代码才知道,有更简单的方法, 只要去w/3/n, a[0], a[n]/2 的最小值就好了
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <math.h>
using namespace std;
#pragma warning(disable:4996)
typedef long long LL;
const int INF = <<;
const double eps = 1e-;
/* */
int a[ + ];
int main()
{
int n, w;
double ans = ;
while (scanf("%d%d", &n,&w) != EOF)
{
int m = * n;
for (int i = ; i < m; ++i)
{
scanf("%d", &a[i]);
}
sort(a, a + m);
ans = (double)w / / n;
ans = min(ans, (double)a[]);
ans = min(ans, (double)a[n] / );
printf("%lf", ans**n);
}
return ;
}
C题
给我们n,表示有n条桌腿,
然后接下来n个数字,Li表示桌腿的长度,
再接下来n个数组,di表示砍掉第i的桌腿的费用。
一个桌子要是稳定的,要求桌子最长的桌腿的条数占总条数的一半以上
问使得桌子稳定的最小花费
思路:将桌腿按长度排序,然后遍历桌腿,枚举桌腿的长度x作为最长的桌腿,那么比x长的桌腿应该去掉,
比x长的桌腿都排在x后面,所以我们可以维护一个后缀和,使得可以在O(1)的时间内获得砍掉比x长的所有桌腿的费用
设长度为x的桌腿有cnt条,那么要将比x短的桌腿砍掉剩下cnt-1条即可。 砍的时候,肯定是先砍费用小的。
比赛时的想法是用优先队列维护一个费用队列,队头的费用最小。但是时间复杂度超了(不去算算法的时间复杂度果然是不好的习惯)
其实费用的取值是1-->200,所以只要用个标记数组来标记,每次只要遍历标记数组就可以了。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <math.h>
#include <functional>
using namespace std;
#pragma warning(disable:4996)
typedef long long LL;
const int INF = <<;
/* */
const int N = + ;
struct Node
{
int l, d;
bool operator<(const Node&rhs)const
{
return l < rhs.l;
}
}a[N];
int suffix[N],c[N];
void input(int &x)
{
char ch = getchar();
while (ch < '' || ch>'')
ch = getchar();
x = ;
while (ch >= '' && ch <= '')
{
x = x * + ch - '';
ch = getchar();
}
}
int main()
{
int n, i, j, ans, k, total;
while (scanf("%d", &n)!=EOF)
{
total = ;
for (i = ; i < n; ++i)
input(a[i].l);
for ( i = ; i < n; ++i)
input(a[i].d); sort(a, a + n);
for (i = ; i < n; ++i)
suffix[i] = a[i].d;
for (i = n - ; i >= ; --i)
suffix[i] += suffix[i + ];
i = ;
ans = INF;
while (i < n)
{
int tmp = a[i].l;
j = i;
while (i < n && a[i].l == tmp)
i++;
int cnt = i - j;
tmp = ;
//砍掉比x更长的桌腿
if (i<n)
tmp = suffix[i];
//total统计的是比x短的桌腿条数
int t = total; for (k = ; k <= ; ++k)
{
if (t < cnt)
break;
if (t - c[k] >= cnt - )
{
tmp += c[k] * k;
t -= c[k];
}
else
{
tmp += k * (t - cnt + );
break;
}
} for (k = j; k < i; ++k)
{
c[a[k].d]++;
total++;
}
ans = min(ans, tmp);
}
printf("%d\n", ans);
}
return ;
}
D题:
给定一个图,问最少要加多少条边才使得图有长度为奇数的环。并输出方案数。
第一种情况:如有m=0,那么考虑一个环最少有3个点,3条边,所以我们要从n个点中选3个点,并且加上3条边就可以形成环
方案书是C(n,3)
第二种情况:每个点的度数不超过1(即图的最大连通分量只有2个点),那么只要加2条边,且方案数为 2个点的连通分量加独立的点形成的方案数(n-2*m)*n
+ 2个点的连通分量加2个点的连通分量所形成环的方案书 2*m(m-1)
第三种情况:那么肯定最大连通分量有3个点,那么只要加1条边就可以了。所以只要将图染色,将黑色的点,或者白色的点连起来就形成环了
方案数是所有连通分量的 C(黑色,2) + C(白色,2)
当然了,如果图本身就存在奇数环, 那么输出0 1 就好了
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <math.h>
using namespace std;
#pragma warning(disable:4996)
typedef long long LL;
const int INF = <<;
/* */
const int N = + ;
vector<int> g[N];
int d[N];
int color[N];
bool hasOddCycle;
void dfs(int u, int fa,int &cnt, int &black)
{ for (int i = ; i < g[u].size(); ++i)
{
int v = g[u][i];
if (v == fa) continue;
if (color[v] == -)
{
color[v] = color[u] ^ ;
black += color[v];
cnt += ;
dfs(v, u, cnt, black);
}
else if (color[u] == color[v])
{
hasOddCycle = true;
} }
}
int main()
{
int n, m, a, b;
bool flag = false;
scanf("%d%d", &n, &m);
if (m == )
{
printf("%d %I64d\n", , (LL)n*(n - )*(n-) / );
return ;
}
for (int i = ; i < m; ++i)
{
scanf("%d%d", &a, &b);
g[a].push_back(b);
g[b].push_back(a);
d[a]++;
d[b]++;
if (d[a]> || d[b] > )
flag = true;
}
if (!flag)
{
printf("%d %I64d\n", , (LL)(n - * m)*m + (LL) * m*(m - ));
return ;
}
memset(color, -, sizeof(color));
LL ans = ;
int cnt, black;
for (int i = ; i <= n; ++i)
{
if (color[i] == -)
{
cnt = black = ;
color[i] = ;
dfs(i, -, cnt, black);
ans += (LL)black*(black - ) / + (LL)(cnt - black)*(cnt - black - ) / ;
}
if (hasOddCycle)
break;
}
if (hasOddCycle)
printf("%d %d\n", , );
else
printf("%d %I64d\n", , ans); return ;
}
E题:
用dp的方法在O(n*n)的时间内求出所有的half-palindrome. 然后将所有的子串都插入字典树中,时间复杂度同样是O(n*n),然后dfs到第k个half-palindrome
dfs的时间复杂度同样是O(n*n),因为字典树的节点数不超过O(n*n)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <math.h>
using namespace std;
#pragma warning(disable:4996)
typedef long long LL;
const int INF = <<;
/*2 */
int root, size, k, m = -;
const int N = + ;
bool ok[N][N];
char str[N], ans[N];
struct Trie
{
int cnt, next[];
void init()
{
cnt = ;
next[] = next[] = -;
}
}trie[N*N]; void add(int i, int n)
{
int cur = root;
for (int j = i; j < n; ++j)
{
if (trie[cur].next[str[j] - 'a'] == -)
{
trie[size].init();
trie[cur].next[str[j] - 'a'] = size++;
}
cur = trie[cur].next[str[j] - 'a'];
if (ok[i][j])
trie[cur].cnt++;
}
}
void dfs(int cur)
{
k -= trie[cur].cnt;
if (k <= )
{
printf("%s\n", ans);
exit();
}
for (int i = ; i < ; ++i)
{
if (trie[cur].next[i] != -)
{
ans[++m] = 'a' + i;
dfs(trie[cur].next[i]);
ans[m--] = ;
}
}
}
int main()
{
scanf("%s%d", str,&k);
int n = strlen(str);
size = ;
trie[root].init();
for (int len = ; len <= n; ++len)
{
for (int i = ; i <= n - len; ++i)
{
int j = i + len - ;
if (j - i <= )
ok[i][j] = str[i] == str[j];
else
ok[i][j] = str[i] == str[j] && ok[i + ][j - ];
}
}
for (int i = ; i < n; ++i)
add(i, n);
dfs(root);
return ;
}
codeforece Round#311 BCDE的更多相关文章
- Codeforces Round #311 (Div. 2) E. Ann and Half-Palindrome 字典树/半回文串
E. Ann and Half-Palindrome Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contes ...
- Codeforces Round #311 (Div. 2) D. Vitaly and Cycle 图论
D. Vitaly and Cycle Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/557/p ...
- Codeforces Round #311 (Div. 2) C. Arthur and Table Multiset
C. Arthur and Table Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/557/p ...
- Codeforces Round #311 (Div. 2)B. Pasha and Tea 水题
B. Pasha and Tea Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/557/prob ...
- Codeforces Round #311 (Div. 2) A. Ilya and Diplomas 水题
A. Ilya and Diplomas Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/557/ ...
- Codeforces Round #311 (Div. 2) D. Vitaly and Cycle 奇环
题目链接: 点这里 题目 D. Vitaly and Cycle time limit per test1 second memory limit per test256 megabytes inpu ...
- Codeforces Round #311 (Div. 2) D - Vitaly and Cycle(二分图染色应用)
http://www.cnblogs.com/wenruo/p/4959509.html 给一个图(不一定是连通图,无重边和自环),求练成一个长度为奇数的环最小需要加几条边,和加最少边的方案数. 很容 ...
- Codeforces Round #311 (Div. 2) E - Ann and Half-Palindrome(字典树+dp)
E. Ann and Half-Palindrome time limit per test 1.5 seconds memory limit per test 512 megabytes input ...
- Codeforces Round #311 (Div. 2)
我仅仅想说还好我没有放弃,还好我坚持下来了. 最终变成蓝名了,或许这对非常多人来说并不算什么.可是对于一个打了这么多场才好不easy加分的人来说,我真的有点激动. 心脏的难受或许有点是由于晚上做题时太 ...
随机推荐
- 关于时间,日期,星期,月份的算法(Java中Calendar的用法)(一)
package cn.outofmemory.codes.Date; import java.util.Calendar; import java.util.Date; public class Ca ...
- 【安卓】eclipse中不可错过的几个秘密、!
1.PackageExplorer显示文件层次的默认方式是平行列出全部包,事实上也可显示成多级,并且效果比navigator好多了. PackageExplorer视图中,"右上角箭头→pa ...
- android解析xml一直报错org.xmlpull.v1.XmlPullParserException
错误: org.xmlpull.v1.XmlPullParserException: Unexpected token (position:TEXT @1:2 injava.io.String ...
- R语言与数据分析之六:时间序列简介
今年在某服装企业蹲点了4个多月,之间非常长一段时间在探索其现货和期货预測.时间序列也是做销售预測的首选,今天和小伙伴分享下时间序列的基本性质和怎样用R来挖据时间序列的相关属性. 首先读入一个时间序列: ...
- [破解]java打包Exe工具 - Jar2Exe Wizard
打包java文件为exe的方法和软件有很多,还有一些开源的软件和一些免费的软件. 我用过的所有打包exe软件中,Jar2Exe Wizard是最好用的,但是只有一个月的试用期,需要的可以从官网下载. ...
- 多字符集(ANSI)和UNICODE及字符串处理方式准则
在我们编写程序的时候,使用最多的是字符串的处理,而ANSI和UNICODE的相互转换经常搞的我们头晕眼乱. 应该说UNICODE是一种比较好的编码方式,在我们的程序中应该尽量使用UNICODE编码方式 ...
- hdu2066一个人的旅行
枚举全部相邻城市,作为起点,多次spfa,然后每次在想去的城市中找出spfa后的距离起点最短的花费时间 #include <iostream> #include <cstring&g ...
- 指尖上的电商---(3)Solr全文搜索引擎的配置
接上篇,Solr的准备工作完毕后,本节主要介绍Solr的安装,事实上Solr不须要安装.直接下载就能够了 1.Solr配置 下载地址 :http://lucene.apache.org/so ...
- 奋斗的孩子的TableView(三篇文章)
http://blog.sina.com.cn/s/blog_a6fb6cc90101i8it.html http://blog.sina.com.cn/s/blog_a6fb6cc90101hhse ...
- OCP读书笔记(15) - 管理SQL性能调优
SQL Tuning Advisor(STA): 使用oracle提供的程序包进行sql优化 SQL> conn scott/tiger SQL), name )); SQL> inser ...