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的情况. 这么简单的题..... 做题的时候脑残了...,今天,贴 ...
随机推荐
- nginx多server配置记录
直接在配置文件(/etc/nginx/nginx.conf)中添加如下代码: server { listen 8080; server_name 192.168.100.174:8080; root ...
- Operating system error 32(failed to retrieve text for this error. Reason: 15105)
一台数据库服务器的事务日志备份作业偶尔会出现几次备份失败的情况,具体的错误信息为: DATE/TIME: 2018/7/30 12:10:52 DESCRIPTION: BackupDiskFi ...
- AD域安装及必要设置
本文主要介绍AD域的安装和程序开发必要的设置. 一.安装AD域 运行dcpromo命令,安装AD域. 步骤: 1.win+R 2.dcpromo 图例: 百度百 ...
- .NET MVC全局异常处理(一)
目录 .NET MVC全局异常处理 IIS配置 静态错误页配置 .NET错误页配置 程序设置 全局异常配置 .NET MVC全局异常处理 一直知道有.NET有相关的配置,但没有实际做过,以为改下设定就 ...
- Linux Swap交换分区探讨
Swap交换分区概念 Linux divides its physical RAM (random access memory) into chucks of memory called pages. ...
- wxWidgets 和 QT 之间的选择
(非原创,网络摘抄) 跨平台的C++ GUI工具库很多,可是应用广泛的也就那么几个,Qt.wxWidgets便是其中的翘楚这里把GTK+排除在外,以C实现面向对象,上手相当困难,而且Windows平台 ...
- 理解OSI参考模型(转)
文章转自 https://www.cnblogs.com/evablogs/p/6709707.html 一个视频网站上不小心搜到网络知识的视频,突然以前大学的没有真正接受的知识点,一下子豁然开朗,赶 ...
- Redtiger SQL注入练习(二)
第六关: 点击 click me,构造url:user=1',返回user not found.user=1'',同样. 猜测是数字型注入,构造order by , user=1 order by ...
- 2018-2019-2 20175329许钰玮 实验二《Java面向对象程序设计》实验报告
实验内容 1.初步掌握单元测试和TDD 2.理解并掌握面向对象三要素:封装.继承.多态 3.初步掌握UML建模 4.熟悉S.O.L.I.D原则 5.了解设计模式 (一)单元测试 对于单元测试中单元的含 ...
- MongoDB Change Stream:简介、尝试与应用
在MongoDB3.6引入的新feature中,change stream无疑是非常吸引人的. Change streams allow applications to access real-tim ...