2013 腾讯马拉松初赛第一场
模拟,同一楼层下去的人不需要多次开门~~~
View Code
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<algorithm> using namespace std; const int N = 110; int a[N],b[N], n; int main(){ int T; scanf("%d",&T); while( T-- ){ scanf("%d", &n); for(int i = 0; i < n; i++ ) scanf("%d",&a[i]); sort( a, a+n ); int s = 0; int cnt = unique( a, a+n ) - a; s = (n-cnt) + 10*a[cnt-1] + 6*cnt; printf("%d\n", s ); } return 0; }
Ax = A( (x-t+n)%n ) * k^t , 二分快速幂求 K^t
View Code
#include<stdio.h> #include<stdlib.h> #include<string.h> const int mod = 1e9+7; typedef long long LL; const int N = 1e4+10; LL a[N], k; int n, t; LL Pow( LL x, LL b ){ LL res = 1; while( b ){ if(b&1) res = res*x%mod; x = x*x%mod; b >>= 1; } return res; } int main(){ int T; scanf("%d", &T); while( T-- ){ scanf("%d%d%lld", &n,&t,&k); k = Pow(k,t); for(int i = 0; i < n; i++){ scanf("%lld", &a[i]); a[i] = a[i]*k%mod; } t %= n; for(int i = 0; i < n; i++){ printf("%lld", a[(i+n-t)%n] ); printf( (i==n-1) ? "\n" : " " ); } } return 0; }
不会~~~ 数位DP,先留 神牛的解题报告链接,学会了后补上
80行精炼代码: http://paste.ubuntu.com/5635973/
适牛解题报告: http://blog.csdn.net/dslovemz/article/details/8540340
完全背包裸题
View Code
#include<stdio.h> #include<string.h> #include<stdlib.h> const int N = 1e5+10; #define MAX(a,b) (a)>(b)?(a):(b) int val[110], cost[110], dp[N]; int n, V; int main(){ while( scanf("%d",&n) != EOF) { for(int i = 0; i < n; i++) scanf("%d%d", &val[i],&cost[i] ); scanf("%d", &V); memset( dp, 0, sizeof(dp) ); for(int i = 0; i < n; i++){ for(int v = cost[i]; v <= V; v++ ) dp[v] = MAX( dp[v], dp[v-cost[i]]+val[i] ); } printf("%d\n", dp[V] ); } return 0; }
区间覆盖问题,题目描述有点坑,对于给定区间 [l,r] , 若 r-l > 0, 才算时间,为 [l,r-1],
因为 r 时间点,并未被使用,比赛时WA了好多次,因为这里。。
解法一: 线段树,区间覆盖 Nlog(N)
View Code
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<algorithm> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 typedef int LL; const int N = 2000; LL sum[N<<2], add[N<<2]; void push_up( int rt ){ sum[rt] = sum[rt<<1] + sum[rt<<1|1]; } void push_down( int rt, int m){ if( add[rt] ){ add[rt<<1] = add[rt]; add[rt<<1|1] = add[rt]; sum[rt<<1] = (LL)(m-(m>>1))*add[rt]; sum[rt<<1|1] = (LL)(m>>1)*add[rt]; add[rt] = 0; } } void build( int l, int r, int rt ){ add[rt] = sum[rt] = 0; if( l == r ) return; int m = (l+r)>>1; build( lson ); build( rson ); //push_up( rt ); } void update( int L, int R, LL c, int l, int r,int rt ){ if( (L<=l) && (r<=R) ){ add[rt] = c; sum[rt] = (LL)c*(r-l+1); return; } push_down( rt, r-l+1 ); int m = (l+r)>>1; if( L <= m ) update( L, R, c, lson ); if( m < R ) update( L, R, c, rson ); push_up( rt ); } LL query( int L, int R, int l, int r, int rt ){ if( (L<=l) && (r<=R) ) return sum[rt]; push_down( rt, r-l+1 ); int m = (l+r)>>1; LL ret = 0; if( L <= m ) ret += query( L, R, lson ); if( m < R ) ret += query( L, R, rson ); return ret; } int main(){ int T, n , maxn = 1500; while( scanf("%d", &n) != EOF) { memset( sum, 0,sizeof(sum)); memset( add, 0, sizeof(add)); build( 1, maxn, 1 ); for(int i = 0; i < n; i++){ int a,b,c,d; scanf("%d:%d",&a,&b); scanf("%d:%d",&c,&d); b = a*60+b+1; d = c*60+d+1; if( b > d ){ int t = b; b = d; d = t; } if( b < d ) update( b,d-1, 1, 1,maxn,1 ); } int ans = 0; // for(int i = 1; i <= 1440; i++) // if( !query( i,i, 1,maxn,1) ) ans++; printf("%d\n", 1440-sum[1] ); } return 0; }
解法二: 因为作用区间只落在 [1,1440] ,虽然区间很多,但是作用点不多, 时间复杂度 O( 1440*1440 )
View Code
#include<stdio.h> #include<string.h> #include<stdlib.h> const int N = 1e5+10; #define MAX(a,b) (a)>(b)?(a):(b) int L[1500], vis[1500], n; int main(){ while( scanf("%d", &n) != EOF) { memset( L, 0xff, sizeof(L)); int a, b, c, d; for(int i = 0; i < n; i++) { scanf("%d:%d %d:%d",&a,&b,&c,&d); b = a*60+b+1; d = c*60+d+1; if( b !=d ) L[b] = MAX( L[b], d-1 ); } memset( vis, 0,sizeof(vis)); int st = 0; for(int i = 1; i <= 1440; i++){ if( L[i] >= st ){ for(int j = i; j <= L[i]; j++) vis[j] = 1; st = L[i]; } } int ans = 0; for(int i = 1; i <= 1440; i++) if( vis[i] ) ans++; printf("%d\n", 1440-ans); } return 0; }
解法三: 从 CSUST 那边得到的解法,对于区间 [l,r] ,转换成 [ +, - ] 这样,未被覆盖的区间就会保持平衡
View Code
#include<stdio.h> #include<math.h> #include<string.h> int t[2000],n,ans; main() { int i,j=0,h1,m1,h2,m2; while(scanf("%d",&n)!=EOF) { ans=0; memset(t,0,sizeof(t)); for (i=1;i<=n;i++) { scanf("%d:%d %d:%d",&h1,&m1,&h2,&m2); t[h1*60+m1]+=1; t[h2*60+m2]-=1; } for (i=0;i<1440;i++) { j+=t[i]; if (j==0) ans++; } printf("%d\n",ans); } }