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的更多相关文章

  1. 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 ...

  2. 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 ...

  3. 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 ...

  4. 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 ...

  5. 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/ ...

  6. Codeforces Round #311 (Div. 2) D. Vitaly and Cycle 奇环

    题目链接: 点这里 题目 D. Vitaly and Cycle time limit per test1 second memory limit per test256 megabytes inpu ...

  7. Codeforces Round #311 (Div. 2) D - Vitaly and Cycle(二分图染色应用)

    http://www.cnblogs.com/wenruo/p/4959509.html 给一个图(不一定是连通图,无重边和自环),求练成一个长度为奇数的环最小需要加几条边,和加最少边的方案数. 很容 ...

  8. 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 ...

  9. Codeforces Round #311 (Div. 2)

    我仅仅想说还好我没有放弃,还好我坚持下来了. 最终变成蓝名了,或许这对非常多人来说并不算什么.可是对于一个打了这么多场才好不easy加分的人来说,我真的有点激动. 心脏的难受或许有点是由于晚上做题时太 ...

随机推荐

  1. QNX 多线程 (线程1每隔20ms读取 number;线程2每隔10ms计算一次)

    #include <pthread.h>#include <stdio.h>#include <sys/time.h>#include <string.h&g ...

  2. 在VC下显示JPEG、GIF格式图像的一种简便方法

    在VC下显示JPEG.GIF格式图像的一种简便方法 一. 引言  JPEG图像压缩标准随然是一种有损图像压缩标准,但由于人眼视觉的不敏感,经压缩后的画质基本没有发生变化,很快便以较高的压缩率得到了广泛 ...

  3. Shell printf 命令

    Shell printf 命令 printf 命令模仿 C 程序库(library)里的 printf() 程序. 标准所定义,因此使用printf的脚本比使用echo移植性好. printf 使用引 ...

  4. 10881 - Piotr's Ants

    Problem D Piotr's Ants Time Limit: 2 seconds "One thing is for certain: there is no stopping th ...

  5. Swift - 属性观察者(willSet与didSet)

    属性观察者,类似于触发器.用来监视属性的除初始化之外的属性值变化,当属性值发生改变时可以对此作出响应.有如下特点: 1,不仅可以在属性值改变后触发didSet,也可以在属性值改变前触发willSet. ...

  6. USM锐化之openCV实现,附赠调整对比度函数

    源地址:http://www.cnblogs.com/easymind223/archive/2012/07/03/2575277.html 常用Photoshop的玩家都知道Unsharp Mask ...

  7. jasperreport报表生成时编译的错误

    在帮徐老板解决一个jasperreport报表生成时编译的错误: 刚开始时,加上他所给的 jar 包之后,错误显示为: net.sf.jasperreports.engine.JRException: ...

  8. SilkTest Q&A 4

    Q31.如何在inc文件里面写函数? A31.在你在inc文件(例如demo.inc)里写好函数以后,你需要使用Use path/Use file来指定指定它们. 在SilkTest中->Opt ...

  9. c++中虚函数和纯虚函数定义

    只有用virtual声明类的成员函数,使之成为虚函数,不能将类外的普通函数声明为虚函数.因为虚函数的作用是允许在派生类中对基类的虚函数重新定义.所以虚函数只能用于类的继承层次结构中. 一个成员函数被声 ...

  10. cronjob不跑得原因

    能是环境的不同,能够在cronjob中加个env > /tmp/env.output查看 应用要同一时候输出标准错误合标准输出到一个文件能够&> /tmp/t