Codeforces Round #244 (Div. 2)
来源:互联网 发布:邮箱大师 mac 编辑:程序博客网 时间:2024/06/01 08:13
这场CF题目的难度不正常啊,很不正常啊!!E题这么简单!!出题人怎么想的 ...
A. Police Recruits
http://codeforces.com/problemset/problem/427/A
题意 : 给你n个数,大于0的数表示有a[i]个police可以派遣, -1 表示这里发生了犯罪需要前面的一个police来平息犯罪 。求有多少犯罪平息不了
思路: 用一个变量sum表示当前可以有多少police可以用,遇到整数则sum+=a[i] , 遇到-1,若sum为0,那么这个犯罪则平息不了,不为0,则sum--。
#include <stdio.h>#include <string.h>int a[100005] ;int main(){int n ;while( scanf( "%d" , &n ) != EOF ) {int ans = 0 ;int sum = 0 ;for( int i = 1 ; i <= n ; i ++ ) {int a ;scanf( "%d" , &a ) ;if( a == -1 ) {if( sum == 0 ) ans ++ ;else sum -- ;}else{sum += a ;}}printf( "%d\n" , ans ) ;}return 0 ;}
B. Prison Transfer
http://codeforces.com/problemset/problem/427/B
题意: 给你n个数,求出有多少长度为c的区间,他的最大值是小于等于t的
思路: 用线段树,树状数组,RMQ什么的都可以搞,我是用单调队列搞的
#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;#define MAXN 200005struct Queue { int top , rear ; struct node { int time , val ; } Q[MAXN]; void clear() { rear = 0; top = 1 ; } void push_back ( int time , int e ) { while ( top <= rear && Q[rear].val <= e ) rear -- ; Q[++rear].time = time; Q[rear].val = e; } void pop_top ( int time ) { while ( Q[top].time <= time ) top ++ ; } int top_val() { return Q[top].val; }}q;int main(){int n , t , c ;while( scanf( "%d%d%d" , &n , &t , &c ) != EOF ) {q.clear() ;for( int i = 1 ; i <= c ; i ++ ) {int a ;scanf( "%d" , &a ) ;q.push_back( i , a ) ;}int cnt = 0 ;if( q.top_val() <= t ) cnt ++ ;int j = 1 ;for( int i = c + 1 ; i <= n ;i ++ ) {int a ;scanf( "%d" , &a ) ; q.push_back( i , a ) ;q.pop_top( j ++ ) ;if( q.top_val() <= t ) cnt ++ ;}printf( "%d\n" , cnt ) ;}return 0 ;}
C. Checkposts
http://codeforces.com/problemset/problem/427/C
题意 : 给你n个点,m条有向边,每个点都有权值,你需要挑选若干个点建立post,要求使每个点都可以到达至少一个post,也至少可以由一个post到达。求挑选的点的最小权值和以及方案数。
思路: 求强连通分量,对于每个连通分量,我们去其中的点的最小值,这样就能达到权值和最小。方案数就每个连通分量中权值为最小权值的点的个数的乘积。注意下不要溢出,不要RE就可以了。
#include<cstdio>#include <cstring>#include <iostream>using namespace std;#define maxn 200005#define maxm 600005struct Edge{ int v; int next;};Edge edge[maxm];//边的集合int node[maxn];//顶点集合int now[maxn]; //新图的顶点集合int instack[maxn];//标记是否在stack中int stack[maxn];int Belong[maxn];//各顶点属于哪个强连通分量int DFN[maxn];//节点u搜索的序号(时间戳)int LOW[maxn];//u或u的子树能够追溯到的最早的栈中节点的序号(时间戳)int n, m;//n:点的个数;m:边的条数int cnt_edge;//边的计数器int Index;//序号(时间戳)int top;int Bcnt;//有多少个强连通分量int Min[maxn] ; // 每个强连通分量的最小权值点int Cnt[maxn] ; // 每个强连通分量的最小权值点的个数void init(){cnt_edge=0;memset(node,-1,sizeof(node));}void add_edge(int u, int v)//邻接表存储{ edge[cnt_edge].next = node[u]; edge[cnt_edge].v = v; node[u] = cnt_edge++;}void tarjan(int u){ int i,j; int v; DFN[u]=LOW[u]=++Index; instack[u]=true; stack[++top]=u; for (i = node[u]; i != -1; i = edge[i].next) { v=edge[i].v; if (!DFN[v])//如果点v没被访问 { tarjan(v); if (LOW[v]<LOW[u]) LOW[u]=LOW[v]; } else//如果点v已经被访问过 if (instack[v] && DFN[v]<LOW[u]) LOW[u]=DFN[v]; } if (DFN[u]==LOW[u]) { Bcnt++; do { j=stack[top--]; instack[j]=false; Belong[j]=Bcnt; } while (j!=u); }}void solve(){ int i; top=Bcnt=Index=0; memset(DFN,0,sizeof(DFN)); memset(LOW,0,sizeof(LOW)); for (i=1;i<=n;i++) if (!DFN[i]) tarjan(i);}int out[maxn],flag[maxn],in[maxn];void suodian()//邻接表形式的新图{int v;memset(now,-1,sizeof(now));memset(out,0,sizeof(out));memset(in,0,sizeof(in));memset(flag,-1,sizeof(flag));//用于判断重边,有些图需要排除重边,而有些则不用,视情况而定for(int u=1;u<=n;u++){for(int i=node[u];i!=-1;i=edge[i].next){v=edge[i].v;if(Belong[u]!=Belong[v]&&flag[Belong[u]]!=Belong[v])//缩点建新图,并统计缩点后各点的出度和入度{flag[Belong[u]]=Belong[v];edge[cnt_edge].v=Belong[v];edge[cnt_edge].next=now[Belong[u]];now[Belong[u]]=cnt_edge++;out[Belong[u]]++;in[Belong[v]]++;}}}}__int64 val[100005] ;int main(){while( scanf( "%d" , &n ) != EOF ) {for( int i =1 ; i <= n; i ++ ) scanf( "%I64d" , &val[i] ) ;scanf( "%d" , &m ) ;init() ;while( m -- ) {int u , v ;scanf( "%d%d" , &u , &v ) ;add_edge( u , v ) ;}solve() ;suodian() ;memset( Min , 0x3f , sizeof(Min) ) ;for( int i = 1 ; i <= n ; i ++ ) {int be = Belong[i] ;if( val[i] < Min[be] ) {Min[be] = val[i] ;Cnt[be] = 1 ;}else if( val[i] == Min[be] ) {Cnt[be] ++ ;}}__int64 ans1 = 0 , ans2 = 1 ;for( int i = 1 ; i <= Bcnt ; i ++ ) {ans1 += Min[i] ;ans2 *= Cnt[i] ;ans2 %= 1000000007 ;}printf( "%I64d %I64d\n" , ans1 , ans2 ) ;}return 0 ;}
D. Match & Catch
http://codeforces.com/problemset/problem/427/D
题意: 给你两个字符串,你需要找到长度最短的,公共字串,并且这个字串在串1中只出现一次,在串2中只出现一次。
思路:不会后缀数组哭了... 不会做
E. Police Patrol
http://codeforces.com/problemset/problem/427/E
题意: 有n个犯罪地点,我们需要选择一个地方作为警察局,从这里出发抓住所有的罪犯,警车做多可以装m个罪犯。求要抓住所有的罪犯的路程最小值是多少。
思路: 首先选择的地点肯定是这n个犯罪地点中的其中一个。我们假设选择的地点在两个犯罪地点x,y的中间,那么假设x左边的点要多余y右边的点,那么我们将建造警察局的点移到x至少不会差于原来的情况。其他情况自己考虑。
那么我们就集中考虑把警察局建在犯罪地点的情况。
我们将整个坐标轴分成n-1份,假设我们选择x作为警察局,那么我们可以知道,前m段肯定只会走一个来回,再接下来的m段肯定会走2个来回 ... 以此类推
那么我们就可以预处理出一个数组L[i] 为以i作为警察局,抓掉i左边的所有罪犯的路径是多少
同样预处理出R[i] , 最后只要枚举这n个点就可以了
#include <stdio.h>#include <string.h>#include <algorithm>#include <math.h>using namespace std;__int64 L[1000005] , R[1000005];__int64 a[1000005] ;int main(){ int n , m ; while( scanf( "%d%d" , &n , &m ) != EOF ) { for( int i = 1 ; i <= n; i ++ ) scanf( "%I64d" , &a[i] ) ; if( m >= n ) { printf( "%I64d\n" , ( a[n] - a[1] ) * 2 ) ; continue ; } L[1] = 0 ; for( int i = 2 ; i <= n ; i ++ ) L[i] = L[i-1] + (__int64)ceil( 1.0 * ( i - 1 ) / m ) * 2 * ( a[i] - a[i-1] ) ; R[n] = 0 ; for( int i = n - 1 ; i >= 1 ; i -- ) R[i] = R[i+1] + (__int64)ceil( 1.0 * ( n - i ) / m ) * 2 * ( a[i+1] - a[i] ) ; __int64 Min = 99999999999999999LL ; for( int i = 1 ; i <= n ; i ++ ) { Min = min( L[i] + R[i] , Min ) ; } printf( "%I64d\n" , Min ) ; } return 0 ;}
- Codeforces Round #244 (Div. 2)
- Codeforces Round #244 (Div. 2)
- Codeforces Round #244 (Div. 2)
- Codeforces Round #244 (Div. 2)
- Codeforces Round #244 (Div. 2) A~C
- Codeforces Round #244 (Div. 2) ABCE
- Codeforces Round #102 (Div. 2)
- Codeforces Round #103 (Div. 2)
- Codeforces Round #103 (Div. 2)
- Codeforces Round #104 (Div. 2)
- Codeforces Round #105 (Div. 2)
- Codeforces Round #105 (Div. 2)
- Codeforces Round #107 (Div. 2)
- Codeforces Round #108 (Div. 2)
- Codeforces Round #110 (Div. 2)
- Codeforces Round #122 (Div. 2)
- Codeforces Round #121 (Div. 2)
- Codeforces Round #124 (Div. 2)
- Problem 10:Summation of primes
- hadoop2.2安装配置日志(完全分布式)
- FOS中断管理
- Java设计模式
- SQL编程实例:Access数据库,两张表的统计,count、sum聚合函数的使用,iif的使用,group by的使用
- Codeforces Round #244 (Div. 2)
- jquery改变元素属性值
- c++ 分解字符串
- uva ``Accordian'' Patience
- git下载源码时只有.git\objects\pack目录下的.pa
- 算法竞赛入门经典 5.4.4多少块土地
- zookeeper分布安装笔记
- Yii 日志与调试 debugtoolbar
- 重构机房收费系统前夕