codeforces-1138 (div2)
想法题是硬伤,面对卡题和卡bug的情况应对能力太差
A.求两个前缀和以及两个后缀和,相邻最小值的最大值。
#include<iostream>
using namespace std;
const int maxn = 1e5 + ;
int a[maxn];
int pre1[maxn],pre2[maxn],erp1[maxn],erp2[maxn];
int main(){
int N; scanf("%d",&N);
for(int i = ; i <= N ; i ++){
scanf("%d",&a[i]);
if(a[i] == ) pre1[i] = pre1[i - ] + ;
else pre2[i] = pre2[i - ] + ;
}
for(int i = N; i >= ; i --){
if(a[i] == ) erp1[i] = erp1[i + ] + ;
else erp2[i] = erp2[i + ] + ;
}
int ans = ;
for(int i = ; i <= N; i ++){
ans = max(ans,min(pre1[i],erp2[i + ]));
ans = max(ans,min(pre2[i],erp1[i + ]));
}
printf("%d",ans * );
return ;
}
A
B.将人分为00,10,01,11四种,总人数已知为ABCD,假设我们需要选择的分别为abcd。
得到方程1.a + b + c + d = n / 2 方程2 b + d = (C - c) + (D - d)
化简方程2得到b + c + 2d = C + D;
CD为已知常数,考虑暴力枚举dc,可推得b,根据方程1可推得a,然后check,时间复杂度O(n²)
#include<iostream>
#include<vector>
#include<algorithm>
#define pb push_back
using namespace std;
const int maxn = ;
struct Node{
int a,b;
int id;
}node[maxn];
char str[maxn];
int Stack[maxn],top;
vector<int>ans;
bool cmp(Node a,Node b){
return a.a + a.b > b.a + b.b;
}
vector<int>aa,ab,ba,bb;
int main(){
int N; scanf("%d",&N);
scanf("%s",str + );
for(int i = ; i <= N ; i ++){
node[i].a = str[i] - '';
node[i].id = i;
}
scanf("%s",str + );
for(int i = ; i <= N ; i ++) node[i].b = str[i] - '';
for(int i = ; i <= N ; i ++){
if(node[i].a + node[i].b == ) aa.pb(i);
else if(node[i].a == && node[i].b == ) ba.pb(i);
else if(node[i].a == && node[i].b == ) ab.pb(i);
else bb.pb(i);
}
int A = aa.size(),B = ba.size(),C = ab.size(),D = bb.size();
for(int d = ; * d <= C + D && d <= D; d++){
for(int c = ; c <= C && c + * d <= C + D;c++){
int b = (C - c) + (D - d) - d;
if(b < || b > B) continue;
int a = (N / ) - b - c - d;
if(a < || a > A) continue;
for(int i = ; i < a; i ++) printf("%d ",aa[i]);
for(int i = ; i < b; i ++) printf("%d ",ba[i]);
for(int i = ; i < c; i ++) printf("%d ",ab[i]);
for(int i = ; i < d; i ++) printf("%d ",bb[i]);
return ;
}
}
puts("-1");
return ;
}
B
C.对每行每列分别离散化,对于一个点的x是交叉点在横竖往前排名较后的位置 加上往后排名较前的位置。
#include<iostream>
#include<vector>
#include<algorithm>
#define pb push_back
#define LL long long
using namespace std;
const int maxn = ;
int N,M;
LL MAP[maxn][maxn];
LL sr[maxn][maxn],sc[maxn][maxn],hr[maxn][maxn],hc[maxn][maxn];
LL Hash[maxn];
int main(){
scanf("%d%d",&N,&M);
for(int i = ; i <= N; i ++){
for(int j = ; j <= M ; j ++){
scanf("%lld",&MAP[i][j]);
}
}
for(int i = ;i <= N ; i ++){
for(int j = ; j <= M; j ++) Hash[j] = MAP[i][j];
sort(Hash + ,Hash + + M);
int cnt = unique(Hash + ,Hash + + M) - Hash - ;
for(int j = ; j <= M ; j ++){
int t = lower_bound(Hash + ,Hash + + cnt,MAP[i][j]) - Hash;
sc[i][j] = t; hc[i][j] = cnt - t;
}
}
for(int j = ; j <= M ; j ++){
for(int i = ; i <= N ; i ++) Hash[i] = MAP[i][j];
sort(Hash + ,Hash + + N);
int cnt = unique(Hash + ,Hash + + N) - Hash - ;
for(int i = ; i <= N; i ++){
int t = lower_bound(Hash + ,Hash + + cnt,MAP[i][j]) - Hash;
sr[i][j] = t; hr[i][j] = cnt - t;
}
}
for(int i = ; i <= N; i ++){
for(int j = ; j <= M; j ++){
if(j != ) printf(" ");
printf("%lld",max(sc[i][j],sr[i][j]) + max(hr[i][j],hc[i][j]));
}
puts("");
}
return ;
}
C
D.没看清楚题目意思为子串之间可以相互重叠,需要求出一个kmp的next数组,然后贪心的迭代最多能放下的数字。
#include<iostream>
#include<vector>
#include<algorithm>
#include<cstring>
#define pb push_back
#define LL long long
using namespace std;
const int maxn = 5e5 + ;
int N,M;
char str1[maxn],str2[maxn];
int Z,O,z,o;
void get_next(char x[],int m,int nxt[]){
int j = ;
nxt[] = ;
for(int i = ; i <= m ; i ++){
while(j && x[i] != x[j + ]) j = nxt[j];
if(x[j + ] == x[i]) j ++;
nxt[i] = j;
}
}
int Next[maxn];
int main(){
Z = O = z = o = ;
scanf("%s%s",str1 + ,str2 + );
for(int i = ;str1[i]; i ++){
if(str1[i] == '') Z++;
else O++;
}
for(int i = ;str2[i]; i ++){
if(str2[i] == '') z++;
else o++;
}
if(z > Z || o > O){
for(int i = ; i < O; i ++) printf("");
for(int i = ; i < Z; i ++) printf("");
}else{
Z -= z; O -= o;
int l = strlen(str2 + );
get_next(str2,l,Next);
o = z = ;
int ans = ;
for(int i = Next[l] + ; i <= l ; i ++){
if(str2[i] == '') o++;
else z++;
}
while(Z - z >= && O - o >= ){
ans++;
Z -= z; O -= o;
}
printf("%s",str2 + );
for(int i = ; i < ans; i ++){
for(int j = Next[l] + ; j <= l; j ++) printf("%c",str2[j]);
}
for(int i = ; i < O; i ++) printf("");
for(int i = ; i < Z; i ++) printf("");
}
return ;
}
D
E.很显然,如果不考虑去重,是一个记录dp[100000][50]的最短路模型,当然,对于这题是不可以的。
对于这样的模型,可以考虑分层图,将这些点拆分为1e5 * 50个点,用所给的条件重新建图。
好处就是可以Tarjan缩点之后跑dp,问题事实上在于前一个连通分量的点和后一个连通分量的点会不会出现同一天的问题。
很显然是不会的,如果一个点可以在星期2到达,然后绕几圈在星期4到达,很显然他绕几圈之后还会在星期2回来,也就是说,2和4事实上可以保证在同一个连通分量里面。
#include<iostream>
#include<queue>
#include<cstdio>
#include<cstdlib>
#define mp make_pair
#define PII pair<int,int>
#define pb push_back
#define fi first
#define se second
using namespace std;
const int maxn = 1e5 * + ;
struct Edge{
int to,next;
}edge[maxn * ];
int head[maxn],tot;
char str[maxn];
int N,M,D;
void init(){
for(int i = ; i <= N * D; i ++) head[i] = -;
tot = ;
}
void add(int u,int v){
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
}
int low[maxn],dfn[maxn],Stack[maxn],Index,top,scc,num[maxn],belong[maxn];
bool InStack[maxn];
void Tarjan(int u){
int v;
low[u] = dfn[u] = ++Index;
Stack[top++] = u;
InStack[u] = true;
for(int i = head[u]; ~i ; i = edge[i].next){
int v = edge[i].to;
if(!dfn[v]){
Tarjan(v);
if(low[u] > low[v]) low[u] = low[v];
}else if(InStack[v] && low[u] > dfn[v]) low[u] = dfn[v];
}
if(low[u] == dfn[u]){
scc++;
do{
v = Stack[--top];
InStack[v] = false;
belong[v] = scc;
}while(v != u);
}
}
bool MAP[][];
vector<int>P[maxn];
int vis[maxn];
int ind[maxn];
int dp[maxn];
inline int cul(int x,int y){
return (x - ) * D + y + ;
}
int main(){
scanf("%d%d%d",&N,&M,&D); init();
for(int i = ; i <= M ; i ++){
int u,v;
scanf("%d%d",&u,&v);
for(int d = ;d < D; d ++){
int t = (d + ) % D;
add(cul(u,d),cul(v,t));
// cout << cul(u,d) << " " << cul(v,t) << endl;
}
}
for(int i = ; i <= N ; i ++){
scanf("%s",str);
for(int j = ; j < D; j ++){
MAP[i][j] = str[j] - '';
}
}
for(int i = ; i <= N * D; i ++) if(!dfn[i]) Tarjan(i);
top = ;
for(int i = ; i <= N ; i ++){
for(int d = ; d < D; d ++){
if(!MAP[i][d]) continue;
int id = belong[cul(i,d)];
if(vis[id]) continue;
num[id]++; vis[id] = ;
Stack[++top] = id;
}
for(int j = ; j <= top; j ++){
vis[Stack[j]] = ;
}
top = ;
}
for(int i = ; i <= N * D; i ++){
for(int j = head[i]; ~j ; j = edge[j].next){
int v = edge[j].to;
if(belong[i] != belong[v]){
ind[belong[i]]++;
P[belong[v]].pb(belong[i]);
}
}
}
queue<int>Q;
for(int i = ; i <= scc; i ++){
if(!ind[i]){
dp[i] = num[i];
Q.push(i);
}
}
while(!Q.empty()){
int u = Q.front(); Q.pop();
for(int i = ; i < P[u].size(); i ++){
int v = P[u][i];
dp[v] = max(dp[v],dp[u] + num[v]);
ind[v]--;
if(!ind[v]) Q.push(v);
}
}
int ans = dp[belong[]];
printf("%d\n",ans);
return ;
}
E
codeforces-1138 (div2)的更多相关文章
- Codeforces #180 div2 C Parity Game
// Codeforces #180 div2 C Parity Game // // 这个问题的意思被摄物体没有解释 // // 这个主题是如此的狠一点(对我来说,),不多说了这 // // 解决问 ...
- Codeforces #541 (Div2) - E. String Multiplication(动态规划)
Problem Codeforces #541 (Div2) - E. String Multiplication Time Limit: 2000 mSec Problem Descriptio ...
- Codeforces #541 (Div2) - F. Asya And Kittens(并查集+链表)
Problem Codeforces #541 (Div2) - F. Asya And Kittens Time Limit: 2000 mSec Problem Description Inp ...
- Codeforces #541 (Div2) - D. Gourmet choice(拓扑排序+并查集)
Problem Codeforces #541 (Div2) - D. Gourmet choice Time Limit: 2000 mSec Problem Description Input ...
- Codeforces #548 (Div2) - D.Steps to One(概率dp+数论)
Problem Codeforces #548 (Div2) - D.Steps to One Time Limit: 2000 mSec Problem Description Input Th ...
- 【Codeforces #312 div2 A】Lala Land and Apple Trees
# [Codeforces #312 div2 A]Lala Land and Apple Trees 首先,此题的大意是在一条坐标轴上,有\(n\)个点,每个点的权值为\(a_{i}\),第一次从原 ...
- Codeforces #263 div2 解题报告
比赛链接:http://codeforces.com/contest/462 这次比赛的时候,刚刚注冊的时候非常想好好的做一下,可是网上喝了个小酒之后.也就迷迷糊糊地看了题目,做了几题.一觉醒来发现r ...
- codeforces #round363 div2.C-Vacations (DP)
题目链接:http://codeforces.com/contest/699/problem/C dp[i][j]表示第i天做事情j所得到最小的假期,j=0,1,2. #include<bits ...
- codeforces round367 div2.C (DP)
题目链接:http://codeforces.com/contest/706/problem/C #include<bits/stdc++.h> using namespace std; ...
- codeforces 235 div2 C Team
题目:http://codeforces.com/contest/401/problem/C 题意:n个0,m个1,求没有00或111的情况. 这么简单的题..... 做题的时候脑残了...,今天,贴 ...
随机推荐
- ASP.NET Zero--解决方案结构(层)
解决方案结构(层) 创建和下载项目后,您将具有如下所示的解决方案结构: 解决方案有8个项目: Core项目包含域层类(如 实体 和 域服务). Application项目包含应用程序逻辑(如应用程序服 ...
- Python简介之探观止矣
Python是一门什么样的编程语言编程语言主要分为编译型和解释型,静态语言和动态语言,强类型和弱类型,混合语言等.编译型语言:通过编译器把源代码编译(compile)成机器语言,在经过链接(linke ...
- LeetCode算法题-Subtree of Another Tree(Java实现)
这是悦乐书的第265次更新,第278篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第132题(顺位题号是572).给定两个非空的二进制树s和t,检查树t是否具有完全相同的 ...
- 如何用Nginx解决前端跨域问题?
前言 在开发静态页面时,类似Vue的应用,我们常会调用一些接口,这些接口极可能是跨域,然后浏览器就会报cross-origin问题不给调. 最简单的解决方法,就是把浏览器设为忽略安全问题,设置--di ...
- idea软件破解汉化
→http://idea.lanyus.com/上可以找到最新的破解补丁,下载并放到软件的bin目录下 →更改bin目录下的两个文件:Idea.exe.vmoptions和Idea64.exe.vm ...
- 如何删除windows中运行的历史记录
参照下图进入到注册表,依次打开红圈中的路径,在RunMRU里面列出来的全部是记录,全部删除即可
- TCP/IP及内核参数优化调优
Linux下TCP/IP及内核参数优化有多种方式,参数配置得当可以大大提高系统的性能,也可以根据特定场景进行专门的优化,如TIME_WAIT过高,DDOS攻击等等.如下配置是写在sysctl.conf ...
- 这可能是把ZooKeeper概念讲的最清楚的一篇文章
我本人曾经使用过 ZooKeeper 作为 Dubbo 的注册中心,另外在搭建 Solr 集群的时候,我使用到了 ZooKeeper 作为 Solr 集群的管理工具. 前几天,总结项目经验的时候,我突 ...
- yum源 Python3 Django mysql安装
yum 源安装 yum源位置: yum源仓库的地址 在/etc/yum.repos.d/,并且只能读出第一层的repo文件 yum仓库的文件都是以.repo结尾的 linux软件包管理 yum工具如同 ...
- springboot+mybatis+pagehelper
springboot+mybatis+pagehelper整合 springboot 版本2.1.2.RELEASE mybatis 版本3.5 pagehelper 版本5.18 支持在map ...