Codeforces Round #311 (Div. 2) A,B,C,D,E
思路:水题了, 随随便便枚举一下,分情况讨论一下就OK了。
code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cmath>
#define inf 1000000
#define clr(x, y) memset(x, y, sizeof x) using namespace std; int rmina,rmaxa;
int rminb,rmaxb;
int rminc,rmaxc;
int n; int main()
{
scanf("%d", &n);
scanf("%d%d%d%d%d%d", &rmina, &rmaxa, &rminb, &rmaxb, &rminc, &rmaxc);
int d = n - rminb - rminc;
if (d > rmaxa)
{
d = n - rmaxa - rminc;
if (d > rmaxb)
{
d = n - rmaxa - rmaxb;
printf("%d %d %d\n", rmaxa, rmaxb, d);
}
else printf("%d %d %d\n", rmaxa, d, rminc);
}
else printf("%d %d %d\n", d, rminb, rminc); return 0;
}
题意:一共同拥有w升水,有n个男生和n个女生。每一个人都有一个有容量限制a[i]的杯子。每一个男生分到的水容量相等。每一个女生分到的水容量相等。且每一个男生分到的水是女生的二倍。问全部人能分到水的容量的最大值是多少。
思路:设x为在总终状态下每一个女生分到的水的量。a代表女生的最小容量,b代表男生的最小容量。则有x = min(a,b/2,w/3*n)。则 ans = x * 3* n
code :
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
#define clr(x, y) memset(x, y, sizeof x)
#define inf 1000000000
using namespace std; const int maxn = 300005; int a[maxn];
int n, w; int main()
{
scanf("%d%d", &n, &w);
for (int i = 0; i < 2*n; i++) scanf("%d", &a[i]);
sort(a, a + 2*n);
double x0 = (double)w / (3*n);
double x1 = (double)a[0];
double x2 = (double)a[n] / 2; x0 = min(x0, x1);
x0 = min(x0, x2); x0 = x0 * 3 * n; printf("%f\n", x0); return 0;
}
题意:给一个有n个腿的桌子,每一个腿有其长度li,同一时候移除某个腿须要消费di的能量,当长度为最大值的腿的个数大于桌腿的总数的时候,桌子处于平稳状态,输入给出n,li,di问将桌子变成平稳状态所须要的耗费的能量的最小值。
思路:第一眼看上去肯定是要去枚举最大长度的桌腿了,可是怎么样高速的计算确定桌腿后达到平稳状态所须要花费的能量呢? 这个能量包含两部分,一部分是将长度大于当前正在枚举的桌腿的桌腿所有删掉所须要的能量,一部分是删掉使被枚举的长度的桌腿个数大于一半所要消耗的能量。 一開始我把所有的注意力所有都放在了单个的桌腿上,然后在计算复杂度的时候怎么算都感觉会超时。 后来才注意到题目的key ------- di 的大小仅仅有200, 能够依照di对桌脚进行分类, 然后从小到大来枚举di,问题就迎刃而解了~~
code:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
#define clr(x, y) memset(x, y, sizeof x)
#define inf 1000000000
using namespace std; const int maxn = 100005; int n;
int L[maxn];
int D[maxn]; int sum[maxn];
int cnt[maxn];
int cnt_d[maxn]; struct pp
{
int li, di; pp(int a = 0, int b = 0) : li(a), di(b) {} } P[maxn]; bool cmp(pp A, pp B)
{
return A.li > B.li;
} int main()
{
scanf("%d", &n);
for (int i = 0; i < n; i++) scanf("%d", &L[i]);
for (int i = 0; i < n; i++) scanf("%d", &D[i]);
for (int i = 0; i < n; i++) P[i] = pp(L[i],D[i]); clr(sum, 0); clr(cnt, 0); clr(cnt_d, 0); for (int i = 0; i < n; i++)
{
sum[L[i]] += D[i];
cnt[L[i]] ++;
cnt_d[D[i]] ++;
} sort(P, P + n, cmp); int coa, ss, cnta, ans; coa = 0;
cnta = 0;
ans = inf; for (int i = 0; i < n; i++)
{
ss = coa;
int v = P[i].li;
int j;
for (j = i; j < n; j++)
{
if (P[j].li != v) break;
cnt_d[P[j].di]--;
}
i = j-1; int nn = n - cnta;
int cha;
if (cnt[v] == 1) cha = nn - 1;
else cha = nn - (cnt[v] - 1) * 2 - 1;
for (int i = 1; i <= 200; i++)
{
if (cha > cnt_d[i])
{
ss += cnt_d[i] * i;
cha -= cnt_d[i];
}
else
{
if (cha >= 0) ss += i * cha;
break;
}
}
ans = min(ans, ss);
cnta += cnt[v];
coa += sum[v];
} printf("%d\n", ans); return 0;
}
题意:给出一个无向图(图可能不联通)。问最少增加多少条边能够使图具有一个奇环,并计算有多少种加边的方法。
思路: 题目事实上不是非常难。可是自己做的时候也是磨了好久才把题目给磨出来, 做法是这种:首先有一个大家都懂的事实:要构成奇环增加边的个数不会超过3条。然后再分情况讨论增加0,1,2,3条边的情况。
首先对图进行黑白染色,在染色的同一时候统计每一个联通块中黑色节点的个数。 还有白色节点的个数。然后讨论
Case 0: 假设存在一个联通块黑白染色不成功。则肯定存在一个奇环,此时所须要增加的边数就为0,其方案数固定为1。(假设有一条边的两端颜色是一样的则染色不成功)
Case 1: 对于一个联通块。假设用一条边将两个黑色点或者白色点连起来,就能形成一个奇环。所以就能够通过一開始所统计的每一个联通块中黑白节点的个数高速的计算出来。
Case 2: 假设每一个联通块都是1个顶点或者两个顶点,则用2条边就能形成环,这样的就统计一下一个点的连通块和两个点的连通块各有多少个再用组合数学搞一搞即可了。
Case 3: 所有是独立点的情况, 从中任意取三个点就能够了~~~
ps: 黑白染色事实上直接跑一遍dfs(or bfs) 即可了。 我太年轻的先跑了一个生成树,然后则染色,事实上没有必要~。
code:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
#define clr(x, y) memset(x, y, sizeof x)
#define inf 1000000000
using namespace std; const int maxn = 200005; vector<int> G[maxn]; struct edge
{
int st,ed;
bool flag;
} E[maxn]; int n, m;
int par[maxn];
int col[maxn];
int white[maxn];
int black[maxn];
int ta; void init(int n_)
{
for(int i = 0; i <= n_; i++) par[i] = i;
} int Find(int x)
{
if (x == par[x]) return x;
return par[x] = Find(par[x]);
}
void unit(int x, int y)
{
x = Find(x);
y = Find(y);
if (x == y) return ;
par[y] = x;
}
bool same(int x, int y)
{
return Find(x) == Find(y);
} void dfs(int u, int &wh, int &bl)
{
for(int i = 0; i < G[u].size(); i++)
{
int v = G[u][i];
if (col[v] != -1) continue;
col[v] = col[u]^1;
col[v] == 0? wh++ : bl++;
dfs(v, wh, bl);
}
} int main()
{
scanf("%d%d", &n, &m);
int st, ed;
for (int i = 0; i < m; i++)
{
scanf("%d%d", &E[i].st, &E[i].ed);
E[i].flag = false;
}
init(n);
for (int i = 0; i < m; i++)
{
if (!same(E[i].st, E[i].ed))
{
unit(E[i].st, E[i].ed);
G[E[i].st].push_back(E[i].ed);
G[E[i].ed].push_back(E[i].st);
E[i].flag = true;
}
}
clr(col, -1); clr(white, 0); clr(black, 0); ta = 0;
for (int i = 1; i <= n; i++)
{
if (col[i] == -1)
{
int wh = 1;
int bl = 0;
col[i] = 0;
dfs(i, wh, bl);
white[ta] = wh;
black[ta++] = bl;
}
}
for (int i = 0; i < m; i++)
{
if (E[i].flag == true) continue;
if (col[E[i].st] == col[E[i].ed])
{
printf("0 1\n");
return 0;
}
}
long long w = 0;
for (int i = 0; i < ta; i++)
{
if (white[i] > 1) w += (long long)white[i]*(white[i]-1)/2;
if (black[i] > 1) w += (long long)black[i]*(black[i]-1)/2;
}
if (w > 0)
{
printf("1 %lld\n", w);
return 0;
}
int cnt = 0;
int tmp = n;
for (int i = 0; i < ta; i++)
{
if (white[i]+black[i] > 1) cnt++;
}
for (int i = 0; i < ta; i++)
{
if (white[i]+black[i] > 1)
{
cnt--;
tmp -= 2;
w += tmp;
w += 2*cnt;
}
else
{
tmp --;
w += cnt;
}
}
if (w > 0)
{
printf("2 %lld\n", w);
return 0;
}
w += (long long)n*(n-1)*(n-2)/6;
printf("3 %lld\n", w);
return 0; }
E. Ann and Half-Palindrome
题意: 首先题目定义了一个半回文串:一个串是半回文串,当且仅当。这个中间轴左边的奇数位置上的字符与其对称位置上的字符同样,题目给出一个串s,和整数k让你求出s的全部半回文子串中字典序第k大的串。s的长度是5000。
思路:这道题目做起来也可谓是波折满满啊, 一開始听刘神说是暴力,就自己敲了一个最最暴力的做法,尼玛啊O(n^3)的方法你怕不怕。然后一算肯定超时啊,就在想怎么来优化,感觉枚举子串的地方没有什么可优化的了。 就在想判回文的地方有没有什么能够更快的方法,没想出来(还是太弱了),然后刘神告诉我说用区间dp的思想随便预处理一下即可了,顿时恍然大悟,立即又去改了一发,发现超内存 ->___->,然后刘神有告诉我说用动态字典树啊。然后我就去改了字典树。发现T了~~~~, 一看刘神的姿势才发现字典树的插入是O(n)的。可是他没插入一个就相当于插入了全部的以插入串开头的前缀子串,所以在枚举子串的时候仅仅有枚举头即可了~~~。又改了一发最后才过...
当中字典树的每一个节点都多维护一个域用来存,其子树中有多少个半回文串,之后找第K大的串就用类似平衡树上dfs查找某个节点的思想不断的查找左右子树即可了。当中另一些小的细节须要注意~~~
code:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
#define clr(x, y) memset(x, y, sizeof x)
#define inf 1000000000
using namespace std; string s;
int k;
vector<string> vv; int dp[5005][5005]; int dfs(int i, int j)
{
if (i == j) return dp[i][j] = 1;
if (j < i) return dp[i][j] = 1; if (dp[i][j] != -1) return dp[i][j];
if (dfs(i+2,j-2) && s[i] == s[j]) return dp[i][j] = 1;
return dp[i][j] = 0;
} class Trie
{
public:
int flag;
int num;
Trie* next[2];
Trie()
{
flag=0;
num=0;
next[0] = next[1] = 0;
}
} * root; int dfs(Trie * p)
{
if (!p) return 0;
p->num += p->flag;
p->num += dfs(p->next[0]);
p->num += dfs(p->next[1]);
return p->num;
}
string solve(Trie * p, int k)
{
Trie * lson = p->next[0], *rson = p->next[1];;
int lnum, rnum;
if (lson == 0) lnum = 0;
else lnum = lson->num;
if (rson == 0) rnum = 0;
else rnum = rson->num; if (p->flag >= k) return "";
else if (lnum + p->flag >= k) return "a" + solve(lson,k-p->flag);
else return "b" + solve(rson, k - lnum - p->flag);
} void Trie_insert(int st, int ed)
{
Trie* p= root;
for(int i = st; i < ed; i++)
{
int index;
if (s[i] == 'a') index = 0;
else index = 1; if(!p->next[index]){
p->next[index]=new Trie;
}
p=p->next[index];
if (dfs(st,i)) p->flag++;
}
} int main()
{
cin>>s>>k;
int len = s.length();
clr(dp, -1);
root = new Trie();
for (int i = 0; i < len; i++)
{
Trie_insert(i, len);
}
dfs(root);
cout<< solve(root,k) <<endl; return 0;
}
补完了一场题目。给自己加个油~~
Codeforces Round #311 (Div. 2) A,B,C,D,E的更多相关文章
- 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) 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) 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)
我仅仅想说还好我没有放弃,还好我坚持下来了. 最终变成蓝名了,或许这对非常多人来说并不算什么.可是对于一个打了这么多场才好不easy加分的人来说,我真的有点激动. 心脏的难受或许有点是由于晚上做题时太 ...
随机推荐
- 通讯录结构体方法的实现 和VS中存在的一些问题的分析
实现一个通讯录: 通讯录能够用来存储1000个人的信息.每一个人的信息包含: 姓名.性别.年龄.电话.住址 功能例如以下: 1. 加入联系人信息 2. 删除指定联系人信息 3. 查找指定联系人信 ...
- 【CentOS6.5】安装之DNS配置错误,yum install 软件报错:ERROR 6或者56错误提示”could not retrieve mirrorlist http://mirrorlist.centos.org ***”
刚安装完CentOS,使用yum命令安装一些常用的软件,使用如下命令:yum grouplist | more. 提示如下错误信息: Loaded plugins: fastestmirror Set ...
- easyui框架Date日期类型以json形式显示到前台datagrid时,显示为[object Object]
如下图,easyui当后台把时间数据返回转换成json然后加载在easyui的datagrid里面,显示为[object Object] 需要对时间格式添加格式的显示方法 /** * 时间格 ...
- RTTI、dynamic_cast、typeid、类与类之间的关系uml
一.RTTI Run-time type information (RTTI) is a mechanism that allows the type of an object to be deter ...
- IOS性能调优系列:使用Allocation动态分析内存使用情况
硬广:<IOS性能调优系列>第三篇,持续更新,欢迎关注. <IOS性能调优系列:Analyze静态分析>介绍了使用静态分析方法查找IOS内存泄漏的方法,<IOS性能调优系 ...
- 从 "org.apache.hadoop.security.AccessControlException:Permission denied: user=..." 看Hadoop 的用户登陆认证
假设远程提交任务给Hadoop 可能会遇到 "org.apache.hadoop.security.AccessControlException:Permission denied: use ...
- iOS中Storyboard使用要点记录
摘要: Storyboard的使用与原本单个xib文件的使用还是有些不同的,于习惯上会有些出入.在这里记下遇到的要点. 1.将第一个ViewController用设置成NavigationContro ...
- 浅谈PCIe体系结构(详细剖析PCIE数据流向)
<PCI-Express 体系结构导读> <浅谈PCIe体系结构> http://blog.sina.com.cn/s/articlelist_1685243084_3_1.h ...
- gzexe加密 脚本
sh-4.1# vi GZEXE.sh sh-4.1# cat GZEXE.sh #!/bin/bash echo "gzexe加密实验!!!" >> Cgzexe.l ...
- CShopDialog类
#ifndef SHOP_H #define SHOP_H #include "XWidget.h" #include "GameConfig.h" class ...