2013 腾讯马拉松初赛第一场

小Q系列故事——电梯里的爱情

  模拟,同一楼层下去的人不需要多次开门~~~

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;
}

吉哥系列故事——恨7不成妻

  不会~~~ 数位DP,先留 神牛的解题报告链接,学会了后补上

     80行精炼代码: http://paste.ubuntu.com/5635973/

  适牛解题报告: http://blog.csdn.net/dslovemz/article/details/8540340

D 湫湫系列故事——减肥记I

  完全背包裸题

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;
}

湫湫系列故事——减肥记II

  区间覆盖问题,题目描述有点坑,对于给定区间 [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);
    }

}
原文地址:https://www.cnblogs.com/yefeng1627/p/2976436.html