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加分的人来说,我真的有点激动. 心脏的难受或许有点是由于晚上做题时太 ...
随机推荐
- dialog开发
dialog开发屏幕编程:ok_code在程序里用sy-ucomm接受 调用其他事物代码:call transaction ‘SE38’. 1:50 选择屏幕之屏幕按钮: selection-scre ...
- 积累的VC编程小技巧之框架窗口及其他
1.修改主窗口风格 AppWizard生成的应用程序框架的主窗口具有缺省的窗口风格,比如在窗口标题条中自动添加文档名.窗口是叠加型的.可改变窗口大小等.要修改窗口的缺省风格,需要重载CWnd::Pre ...
- VC/MFC 使edit控件不能进行粘贴操作
这里使用消息拦截的方法 BOOL PersonDlg::PreTranslateMessage(MSG* pMsg) { if (GetDlgItem(IDC_EDIT_USER_ID)->m_ ...
- 14.2.2 InnoDB Multi-Versioning InnoDB 多版本
14.2.2 InnoDB Multi-Versioning InnoDB 多版本: InnoDB 是一个多版本的存储引擎: 它保留信息关于改变数据的老版本,为了支持事务功能 比如并发和回滚. 这些信 ...
- cct软件测试
<全国计算机等级考试三级教程:软件测试技术(2016年版)>根据教育部考试中心制订的<全国计算机等级考试三级软件测试技术考试大纲(2013年版)>编写而成.主要内容包括软件测试 ...
- Oracle 验证IOT表数据存储在主键里
iot表测试: 在create table语句后面使用organization index,就指定数据表创建结构是IOT.但是在不指定主键Primary Key的情况下,是不允许建表的. create ...
- RotateDisp – 一键旋转显示画面 - 小众软件
RotateDisp – 一键旋转显示画面 - 小众软件 RotateDisp – 一键旋转显示画面
- C++内存管理学习笔记(6)
/****************************************************************/ /* 学习是合作和分享式的! /* Auth ...
- Android WebView挂马漏洞--各大厂商纷纷落马
本文章由Jack_Jia编写,转载请注明出处. 文章链接: http://blog.csdn.net/jiazhijun/article/details/11131891 作者:Jack_Jia ...
- Selenium来抓取动态加载的页面
一般的爬虫都是直接使用http协议,下载指定url的html内容,并对内容进行分析和抽取.在我写的爬虫框架webmagic里也使用了HttpClient来完成这样的任务. 但是有些页面是通过js以及a ...