20161104校內訓練

T1 encoding

一道類似模擬的題,就根據所寫的東西來做就可以了。

#include <bits/stdc++.h>
#define rep( i , l , r ) for( int i = (l) ; i <= (r) ; ++i )
#define per( i , r , l ) for( int i = (r) ; i >= (l) ; --i )
#define erep( i , u ) for( int i = head[(u)] ; ~i ; i = e[i].nxt )

using namespace std;
void FileInOut(){
     freopen( "encoding.in" , "r" , stdin );
     freopen( "encoding.out" , "w" , stdout );
}
int solve( int q , int l ){
    if( l == 1 ) return q;
    int mid = l >> 1;
    if( q > mid ){
        return solve( l - q + 1 , l - mid );
    }else{
        return solve( mid - q + 1 , mid ) + (l - mid);
    }
}
int main(){
    FileInOut();
    int N , q;
    scanf("%d %d" , &N , &q);
    cout << solve( q , N ) << endl;
    return 0;
}

T2 Evolve

給你一個序列,求Al...Ar(1ijN) 使得Al|Al+1|...Ar(1ijN)<M 這樣的二元組的個數。

用一個類似單調隊列的東西去維護,因爲| 運算滿足單調性,所以可以這麼做。

#include <bits/stdc++.h>
#define rep( i , l , r ) for( int i = (l) ; i <= (r) ; ++i )
#define per( i , r , l ) for( int i = (r) ; i >= (l) ; --i )
#define erep( i , u ) for( int i = head[(u)] ; ~i ; i = e[i].nxt )

using namespace std;
void FileInOut(){
     freopen( "evolve.in" , "r" , stdin );
     freopen( "evolve.out" , "w" , stdout );
}
inline int _read(){
    int x = 0 , f = 1;
    char ch = getchar();
    while( !isdigit(ch) ){ if( ch == '-' ) f = -1 ; ch = getchar(); }
    while( isdigit(ch) ){
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}
const int maxn = 1000000 + 5;
int a[maxn] , q[50] ;
int main(){
    FileInOut();
    int N = _read() , M = _read() , f = 1 , r = 0;
    rep( i , 1 , N ) a[i] = _read();
    long long ans = 0;
    for( f = 1 , r = 0 ; f <= N ; ++f ){
        if( r < f ){
            ++r;
            rep( i , 0 , 31 ) q[i] += (a[r] >> i & 1);
        }
        int res = 0;
        rep( i , 0 , 31 ) res |= (bool)(q[i]) << i;
        for( ; r < N && (res | a[r + 1]) < M ; ){
            res |= a[++r];
            rep( i , 0 , 31 ) q[i] += (a[r] >> i & 1);
        }
        ans += (long long)(r - f);
        rep( i , 0 , 31 ) q[i] -= (a[f] >> i & 1);
    }
    cout << ans << endl;
    return 0;
}

T3 lover

給你兩種類型的物品,一種可拆分,一種不可以拆分,每個物品都有重量和總價值,問你給你W的揹包,最大價值爲多少。

因爲可拆分的顯然可以用貪心的思路,不可拆分的則用01揹包,最後合併一下就可以了。

#include <bits/stdc++.h>
#define rep( i , l , r ) for( int i = (l) ; i <= (r) ; ++i )
#define per( i , r , l ) for( int i = (r) ; i >= (l) ; --i )
#define erep( i , u ) for( int i = head[(u)] ; ~i ; i = e[i].nxt )

using namespace std;
void FileInOut(){
     freopen( "lover.in" , "r" , stdin );
     freopen( "lover.out" , "w" , stdout );
}
const int maxn = 100 + 5 , maxw = 50000 + 5;
int f[maxw];
double g[maxw];
struct Node{
    int w;
    double p;
} a[maxn];
struct _Node{
    int w , v;
} b[maxn];
inline bool cmp( const Node &t1 , const Node &t2 ){
    return t1.p > t2.p;
}
int main(){
    FileInOut();
    int N = 0 , W = 0 , l1 = 0 , l2 = 0 , v , w , t ;
    scanf("%d %d" , &N , &W );
    rep( i , 1 , N ){
        scanf("%d %d %d" , &w , &v , &t);
        if( 0 == t ) b[++l2].w = w , b[l2].v = v;
        else a[++l1].p = (double)v / w , a[l1].w = w;
    }
    rep( i , 1 , l2 )
        per( j , W , b[i].w )
            f[j] = max( f[j] , f[j - b[i].w] + b[i].v );
    sort( a + 1 , a + l1 + 1 , cmp );
    double res = 0;
    int j , cnt;
    for( j = 1 , cnt = 1 ; j <= W && cnt <= l1 ; cnt++ ){
        while( a[cnt].w ) g[j] = g[j - 1] + a[cnt].p , a[cnt].w-- , ++j ;
    }
    for( ; j <= W ; ++j ) g[j] = g[j - 1];
    double ans = 0;
    rep( i , 0 , W )
        ans = max( ans , g[i] + (double)f[W - i] );
    printf("%.2lf\n" , ans);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章