2013 腾讯马拉松初赛第二场
转换成秒后模拟即可
View Code
#include<stdio.h> #include<stdlib.h> int main(){ int T; scanf("%d", &T); while( T-- ){ int h1,m1,s1; int h2,m2,s2; int mod = 12*60*60; scanf("%d:%d:%d",&h1,&m1,&s1); scanf("%d:%d:%d",&h2,&m2,&s2); s1 = h1*3600+m1*60+s1; s2 = (h2*3600+m2*60+s2)%mod; s1 = (s1-s2+mod)%mod; h2 = s1/3600; m2 = (s1%3600)/60; s2 = s1%60; printf("%02d:%02d:%02d\n", h2, m2, s2 ); } return 0; }
据说是 AC自动机,但是不会
反置,对两串求 最长上升公共子序列,注意中间下标问题
View Code
#include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <map> #include <set> #include <cmath> using namespace std; int seq[205], rseq[205], N; int f[205][205]; inline int Min(int a, int b) { return a > b ? b : a; } inline int Max(int a, int b) { return a > b ? a : b; } void solve(int a[], int b[]) { int max; int Len = -1; int n1 = N, n2 = N; for(int i=1;i<=n1;i++) { max=0; for(int j=1;j<=n2;j++) { f[i][j]=f[i-1][j]; if (a[i]>b[j]&&max<f[i-1][j]) { max=f[i-1][j]; } if (a[i]==b[j]) { f[i][j]=max+1; if (N-j+1 > i) { Len = Max(Len, f[i][j]*2); } else if (N-j+1 == i){ Len = Max(Len, f[i][j]*2-1); } } } } printf("%d\n", Min(Len, N)); } int main() { int T; scanf("%d", &T); while (T--) { scanf("%d", &N); for (int i = 1; i <= N; ++i) { scanf("%d", seq+i); rseq[N-i+1] = seq[i]; } solve(seq, rseq); } return 0; }
分治+扩展KMP, 或者 另外一种处理字符串 M啥
并查集+点分治 , 往上更新的时候合并子树,这样就不会超时
View Code
#include<stdio.h> #include<string.h> #include<stdlib.h> #define MAX(a,b) (a)>(b)?(a):(b) const int N = 1e5+10; const int M = 1e6+10; int n, m; struct node{ int v, c, nxt; }edge[M<<2]; struct Edge{ int u, v, c; void input(){ scanf("%d%d%d",&u,&v,&c); u--; v--; } }Q[M]; int head[N], idx; int st[N], dis[N]; int res; bool vis[N]; int find( int x ){ return (x==st[x]) ? x : (st[x]=find(st[x])) ; } bool legal(){ for(int i = 0; i < n; i++) st[i] = i; for(int i = 0; i < m; i++){ int u = Q[i].u, v = Q[i].v; int x = find(u), y = find(v); if( x == y ) return false; else st[x] = y; } return true; } void addedge(int u,int v,int c){ edge[idx].v = v; edge[idx].c = c; edge[idx].nxt = head[u]; head[u] = idx++; edge[idx].v = u; edge[idx].c = c; edge[idx].nxt = head[v]; head[v] = idx++; } void dfs(int u,int pre ){ if( !vis[u] ) vis[u] = true; for( int i = head[u]; ~i; i = edge[i].nxt ){ int v = edge[i].v; //printf("v = %d\n", v ); if( v != pre ){ dfs( v, u ); res = MAX( res, dis[u]+dis[v]+edge[i].c ); dis[u] = MAX( dis[u], dis[v]+edge[i].c ); } } } int solve(){ memset( head, 0xff, sizeof(head)); idx = 0; for(int i = 0; i < m; i++) addedge( Q[i].u, Q[i].v, Q[i].c ); res = 0; memset( vis, 0, sizeof(vis)); memset( dis, 0, sizeof(dis)); for(int i = 0; i < n; i++) if( !vis[i] ) dfs( i, -1 ); return res; } int main(){ while( scanf("%d%d",&n,&m) != EOF) { for(int i = 0; i < m; i++) Q[i].input(); if( !legal() ) puts("YES"); else printf("%d\n", solve() ); } return 0; }