zoukankan      html  css  js  c++  java
  • 【ACdream】Andrew Stankevich's Contest (22)

    B:1414Geometry Problem

    每两个点之间求距离。选最小的距离作为圆的直径,求出圆心和半径,最后半径加一个小小的数就能够了。


    C:1415 Important Roads

    对起点和终点分别求最短路,得到一定在最短路上的边(满足d[s][u]+w[u][v]+d[u][t]==d[s][t]的边),然后用双连通求桥的方法求边就可以。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    using namespace std ;
     
    typedef long long LL ;
     
    #define rep( i , a , b ) for ( int i = a ; i < b ; ++ i )
    #define For( i , a , b ) for ( int i = a ; i <= b ; ++ i )
    #define rev( i , a , b ) for ( int i = a ; i >= b ; -- i )
    #define travel( e , H , u ) for ( Edge* e = H[u] ; e ; e = e -> next )
    #define clr( a , x ) memset ( a , x , sizeof a )
    #define cpy( a , x ) memcpy ( a , x , sizeof a )
     
    const int MAXN = 20005 ;
    const int MAXE = 400005 ;
    const LL INF = 1e18 ;
     
    struct Edge {
    	int v , c ;
    	Edge* next ;
    } E[MAXE] , *H[MAXN] , *edge ;
     
    struct Seg {
    	int u , v , c ;
    	Seg () {}
    	Seg ( int u , int v , int c ) : u ( u ) , v ( v ) , c ( c ) {}
    } seg[MAXE] ;
     
    struct Node {
    	LL d ;
    	int idx ;
    	Node () {}
    	Node ( LL d , int idx ) : d ( d ) , idx ( idx ) {}
    	bool operator < ( const Node& a ) const {
    		return d > a.d ;
    	}
    } ;
     
    LL dis[2][MAXN] ;
    int vis[MAXN] , Time ;
    int Q[MAXN] , head , tail ;
    int n ;
     
    void clear () {
    	edge = E ;
    	clr ( H , 0 ) ;
    }
     
    void addedge ( int u , int v , int c ) {
    	edge->v = v ;
    	edge->c = c ;
    	edge->next = H[u] ;
    	H[u] = edge ++ ;
    }
     
    void dijkstra ( int s , LL d[] ) {
    	For ( i , 1 , n ) d[i] = INF ;
    	priority_queue < Node > q ;
    	++ Time ;
    	d[s] = 0 ;
    	q.push ( Node ( d[s] , s ) ) ;
    	while ( !q.empty () ) {
    		int u = q.top ().idx ;
    		q.pop () ;
    		if ( vis[u] == Time ) continue ;
    		vis[u] = Time ;
    		travel ( e , H , u ) {
    			int v = e->v ;
    			if ( d[v] > d[u] + e->c ) {
    				d[v] = d[u] + e->c ;
    				q.push ( Node ( d[v] , v ) ) ;
    			}
    		}
    	}
    }
     
    struct BCC {
    	Edge E[MAXE] , *H[MAXN] , *edge ;
    	int dfn[MAXN] , low[MAXN] ;
    	int dfs_clock ;
    	int ans[MAXN] , top ;
    	 
    	void clear () {
    		edge = E ;
    		dfs_clock = 0 ;
    		clr ( H , 0 ) ;
    		clr ( dfn , 0 ) ;
    		clr ( low , 0 ) ;
    	}
    	 
    	void addedge ( int u , int v , int c ) {
    		edge->v = v ;
    		edge->c = c ;
    		edge->next = H[u] ;
    		H[u] = edge++ ;
    	}
    	 
    	void tarjan ( int u , int fa = 0 ) {
    		dfn[u] = low[u] = ++ dfs_clock ;
    		int flag = 1 ;
    		travel ( e , H , u ) {
    			int v = e->v ;
    			if ( v == fa && flag ) {
    				flag = 0 ;
    				continue ;
    			}
    			if ( !dfn[v] ) {
    				tarjan ( v , u ) ;
    				low[u] = min ( low[u] , low[v] ) ;
    				if ( low[v] > dfn[u] ) ans[top ++] = e->c ;
    			} else low[u] = min ( low[u] , dfn[v] ) ;
    		}
    	}
    	 
    	void find_bcc ( int n ) {
    		top = 0 ;
    		For ( i , 1 , n ) if ( !dfn[i] ) tarjan ( i ) ;
    		printf ( "%d
    " , top ) ;
    		sort ( ans , ans + top ) ;
    		rep ( i , 0 , top ) printf ( "%d%c" , ans[i] , i < top - 1 ? ' ' : '
    ' ) ;
    	}
    } G ;
     
    int m ;
     
    void scanf ( int& x , char c = 0 ) {
    	while ( ( c = getchar () ) < '0' || c > '9' ) ;
    	x = c - '0' ;
    	while ( ( c = getchar () ) >= '0' && c <= '9' ) x = x * 10 + c - '0' ;
    }
     
    void solve () {
    	int u , v , c ;
    	clear () ;
    	G.clear () ;
    	For ( i , 1 , m ) {
    		scanf ( u ) , scanf ( v ) , scanf ( c ) ;
    		addedge ( u , v , c ) ;
    		addedge ( v , u , c ) ;
    		seg[i] = Seg ( u , v , c ) ;
    	}
    	dijkstra ( 1 , dis[0] ) ;
    	dijkstra ( n , dis[1] ) ;
    	LL tot_dis = dis[0][n] ;
    	For ( i , 1 , m ) {
    		u = seg[i].u ;
    		v = seg[i].v ;
    		if ( dis[0][u] + seg[i].c + dis[1][v] == tot_dis || dis[0][v] + seg[i].c + dis[1][u] == tot_dis ) {
    			G.addedge ( u , v , i ) ;
    			G.addedge ( v , u , i ) ;
    		}
    	}
    	G.find_bcc ( n ) ;
    }
    
    int main () {
    	clr ( vis , 0 ) ;
    	Time = 0 ;
    	while ( ~scanf ( "%d%d" , &n , &m ) ) solve () ;
    	return 0 ;
    }
    E:1417 Numbers

    对该数求全部比他大的小于等于n的开头为1的最小的数(这个数满足:10^i +(k -(10^i - 1)% k + 1))。


    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std ;
     
    typedef long long LL ;
    #define rep( i , a , b ) for ( int i = a ; i < b ; ++ i )
    #define For( i , a , b ) for ( int i = a ; i <= b ; ++ i )
    #define rev( i , a , b ) for ( int i = a ; i >= b ; -- i )
    #define travel( e , H , u ) for ( Edge* e = H[u] ; e ; e = e -> next )
    #define clr( a , x ) memset ( a , x , sizeof a )
    #define cpy( a , x ) memcpy ( a , x , sizeof a )
     
    const int MAXN = 65 ;
    const int MAXE = 10005 ;
    const int MAXH = 10005 ;
     
    LL n , k ;
    LL a[MAXN] ;
     
    struct String {
    	char s[MAXN] ;
    } s[MAXN] ;
    int cnt = 0 ;
     
    LL pow ( int a , int b ) {
    	LL res = 1 , tmp = a ;
    	while ( b ) {
    		if ( b & 1 ) res *= tmp ;
    		tmp *= tmp ;
    		b >>= 1 ;
    	}
    	return res ;
    }
     
    int cmp ( const String& a , const String& b ) {
    	return strcmp ( a.s , b.s ) < 0 ;
    }
     
    void solve () {
    	cnt = 0 ;
    	a[cnt ++] = k ;
    	For ( i , 1 , 18 ) {
    		LL tmp = pow ( 10 , i ) ;
    		if ( tmp > n ) break ;
    		tmp = tmp + ( k - ( tmp - 1 ) % k - 1 ) ;
    		if ( tmp <= k ) continue ;
    		if ( tmp > n ) break ;
    		a[cnt ++] = tmp ;
    	}
    	rep ( i , 0 , cnt ) sprintf ( s[i].s , "%lld" , a[i] ) ;
    	sort ( s , s + cnt , cmp ) ;
    	printf ( "%s
    " , s[0].s ) ;
    }
     
    int main () {
    	while ( ~scanf ( "%lld%lld" , &n , &k ) && ( n || k ) ) solve () ;
    	return 0 ;
    }

    H:1420 High Speed Trains

    设f(n)为n个城市时满足条件的方案数。

    则f(n)= 全部方案数 - 有一个点没有边覆盖的方案数 - 有两个点没有边覆盖的方案数 - …… - 全都点都没有被覆盖的方案数 = 2^(n*(n-1)/2) - C[n][1] * f(n-1) - C[n][2] * f(n-2) - …… - C[n][n] * f(0)。

    C[i][j]表示从i个里面选j个的组合数。

    边界条件为f(1)=0,f(0)=1。

    JAVA打表AC。


    I:问怎样选择退出的时刻和买保险的时刻来使得期望获得的钱最多。

    枚举结束的时间。每一个时间里面枚举买保险的时间(能够不买)。最后随便搞搞即可了。

    有O(N)的做法。只是懒得搞了。懂了即可了。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    using namespace std ;
      
    typedef long long LL ;
      
    #define rep( i , a , b ) for ( int i = a ; i < b ; ++ i )
    #define For( i , a , b ) for ( int i = a ; i <= b ; ++ i )
    #define rev( i , a , b ) for ( int i = a ; i >= b ; -- i )
    #define travel( e , H , u ) for ( Edge* e = H[u] ; e ; e = e -> next )
    #define clr( a , x ) memset ( a , x , sizeof a )
    #define cpy( a , x ) memcpy ( a , x , sizeof a )
      
    const int MAXN = 55 ;
    const double eps = 1e-8 ;
      
    double dp[MAXN][MAXN] ;
    double p[MAXN] ;
    double pp[MAXN] ;
    LL two[MAXN] ;
    int n , c ;
      
    int dcmp ( double x ) {
    	return ( x > eps ) - ( x < -eps ) ;
    }
      
    void solve () {
    	pp[0] = 1 ;
    	two[0] = 1 ;
    	double ans = 100 ;
    	clr ( dp , 0 ) ;
    	For ( i , 1 , n ) scanf ( "%lf" , &p[i] ) ;
    	For ( i , 1 , n ) p[i] /= 100 ;
    	For ( i , 1 , n ) pp[i] = pp[i - 1] * p[i] ;
    	For ( i , 1 , n ) two[i] = two[i - 1] * 2 ;
    	For ( i , 1 , n ) {
    		For ( j , 1 , i ) {
    			if ( 100 * two[j - 1] <= c ) continue ;
    			double tmp = pp[j - 1] ;
    			double tmp_p = 1 ;
    			For ( k , j + 1 , i ) tmp_p *= p[k] * 2 ;
    			tmp *= ( 100 * two[j - 1] - c ) * ( ( 1 - p[j] ) * tmp_p + p[j] * 2 * tmp_p ) ;
    			ans = max ( ans , tmp ) ;
    		}
    		ans = max ( ans , 100 * two[i] * pp[i] ) ;
    	}
    	printf ( "%.10f
    " , ans ) ;
    }
      
    int main () {
    	while ( ~scanf ( "%d%d" , &n , &c ) ) solve () ;
    	return 0 ;
    }


  • 相关阅读:
    p1706 全排列
    2089烤鸡(类似于选数问题)
    1036选数
    bfs
    A-E
    A-3
    百题A-2
    百题A-1
    二级概念题
    随记
  • 原文地址:https://www.cnblogs.com/wgwyanfs/p/7399686.html
Copyright © 2011-2022 走看看