Codeforces Round #460 (Div. 2)总结

上的分好少。感觉比赛时又傻了。
A:傻逼题
AC代码:

#include <iostream>
#include <cstdio>
typedef long long LL ;
const int MAXN = 5000 ;
const double EPS = 1e-8 ;
const int INF = 0x3f3f3f3f ; 
using namespace std ;

inline int read ( ) {
    int x = 0 , w = 1 ; char c = ' ' ;
    while ( c < '0' || c > '9' ) { c = getchar ( ) ; if ( c == '-' ) w = -1 ; }
    while ( c >= '0' && c <= '9' ) x = ( x << 1 ) + ( x << 3 ) + ( c ^ 48 ) , c = getchar ( ) ;
    return x * w ;
}

int a[MAXN + 5] ;

int main ( ) {
    int n = read ( ) , m = read ( ) ;

    double minv = INF * 1.0 ;

    for ( int i = 1 ; i <= n ; ++i ) {
        int x = read ( ) , y = read ( ) ;
        if ( minv - ( x * 1.0 ) / y >= EPS ) 
            minv = ( x * 1.0 ) / y ;
    }

    printf ( "%.8f" , minv * m ) ;

    return 0 ;
}

B题:暴力大法好。
AC代码:

#include <iostream>
#include <cstdio>
using namespace std ;

int main ( ) {
    int k , i = 0 , Ans = 0 ; 

    cin >> k ;

    while ( ++i ) {
        int t = i , sum = 0 ;
        while ( t ) 
            sum += t % 10 , t/= 10 ;
        if ( sum == 10 ) ++Ans ;
        if ( Ans == k ) break ;
    }

    cout << i << endl ; 

    return 0 ;
}

C:非常裸的前缀和。乱搞搞就出来了。好像有很多人因为用cin超时(大雾)。
AC代码:

#include <iostream>
#include <cstdio>
#define min( a , b ) ( a < b ? a : b )
const int MAXN = 2000 ;
using namespace std ;

int PreL[MAXN + 5][MAXN + 5] , PreR[MAXN + 5][MAXN + 5] , x , Ans ;
char c ;

int main ( ) {
    ios :: sync_with_stdio ( false ) ;

    int n , m , k , sum = 0 ; cin >> n >> m >> k ;

    if ( n == 1 && m == 1 ) {
        char c ; cin >> c ;
        if ( k == 1 && c == '.' ) 
            cout << 1 << endl ;
        else 
            cout << 0 << endl ;
        return 0 ;
    }

    for ( int i = 1 ; i <= n ; ++i )
        for ( int j = 1 ; j <= m ; ++j ) {
            cin >> c ;
            if ( c == '.' ) x = 1 , ++sum ; else x = 0 ;
            PreL[i][j] = PreL[i][j - 1] + x ;
            PreR[i][j] = PreR[i - 1][j] + x ;
        }

    if ( k == 1 ) {
        cout << sum << endl ;
        return 0 ;
    }

    for ( int i = 1 ; i <= n ; ++i ) 
        for ( int j = 1 ; j <= m ; ++j ) {
            if ( j - k < 0 ) continue ;
            if ( PreL[i][j] - PreL[i][j - k] == k ) ++Ans ;
        }

    for ( int i = 1 ; i <= n  ; ++i ) 
        for ( int j = 1 ; j <= m ; ++j ) {
            if ( i - k < 0 ) continue ;
            if ( PreR[i][j] - PreR[i - k][j] == k ) ++Ans ; 
        }

    cout << Ans << endl ;

    return 0 ;
}

D:拓扑排序(判-1)+DP,DP很显然,就是在遍历图+记忆化搜索。状态是dp[n][alpha]。然后考试时没调出来。
AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define max( a , b ) ( a < b ? b : a )
const int MAXN = 300000 ;
const int INF = 0x3f3f3f3f ;
using namespace std ;

inline int read ( ) {
    int x = 0 , w = 1 ; char c = ' ' ;
    while ( c < '0' || c > '9' ) { c = getchar ( ) ; if ( c == '-' ) w = -1 ; }
    while ( c >= '0' && c <= '9' ) x = ( x << 1 ) + ( x << 3 ) + ( c ^ 48 ) , c = getchar ( ) ;
    return x * w ;
}

int c[MAXN + 5] , Ans = 0 , n , m ;
bool f ;

class Graph {
    public :
        struct Node {
            int to , nxt ;
        } edge[MAXN + 5] ;
        Graph ( ) { memset ( head , -1 , sizeof ( head ) ) ; }
        void add ( int u , int v ) {
            edge[tot] = ( Node ) { v , head[u] } , head[u] = tot++ , ++in[v] ;
        }
        int dfs ( int u , int alpha) ;
        void topsort ( ) ;
    private :
        int head[MAXN + 5] , tot , in[MAXN + 5] , dp[MAXN + 5][30] ;
        bool vis[MAXN + 5][30] ;
        queue < int > Q ;
} G ;

void Graph :: topsort ( ) {
    for ( int i = 1 ; i <= n ; ++i ) if ( !in[i] ) Q.push ( i ) ;
    while ( !Q.empty ( ) ) {
        int u = Q.front ( ) ; Q.pop ( ) ; 
        for ( int i = head[u] ; ~i ; i = edge[i].nxt ) {
            int v = edge[i].to ; --in[v] ;
            if ( !in[v] ) Q.push ( v ) ; 
        }
    }
    for ( int i = 1 ; i <= n ; ++i ) 
        if ( in[i] ) {
            f = true ; break ;
        }
}

int Graph :: dfs ( int u , int alpha ) {
    if ( vis[u][alpha] ) return dp[u][alpha] ;
    int ret = 0 ;
    for ( int i = head[u] ; ~i ; i = edge[i].nxt ) {
        int v = edge[i].to ; 
        ret = max ( ret , dfs ( v , alpha ) ) ;
    }
    dp[u][alpha] = ret ;
    if ( c[u] == alpha ) ++dp[u][alpha] ; 
    vis[u][alpha] = true ;
    Ans = max ( Ans , dp[u][alpha] ) ;
    return dp[u][alpha] ;
}

int a[MAXN + 5] ;

int main ( ) {
    n = read ( ) , m = read ( ) ;

    char ch ; 

    for ( int i = 1 ; i <= n ; ++i ) 
        ch = getchar ( ) , c[i] = ch - 'a' ;

    for ( int i = 1 ; i <= m ; ++i ) {
        int u = read ( ) , v = read ( ) ;
        G.add ( u , v ) ;
    }

    G.topsort ( ) ;

    if ( f ) {
        puts ( "-1" ) ;
        return 0 ;
    }

    for ( int i = 1 ; i <= n ; ++i ) {
        for ( int j = 0 ; j <= 25 ; ++j ) 
            if ( j == c[i] ) G.dfs ( i , j ) ;
    }

    printf ( "%d\n" , Ans ) ;

    return 0 ;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值