Codeforces Round #320 (Div. 2)(A~E)

Codeforces Round #320 (Div. 2)

A - Raising Bacteria

題意:

可以理解爲把一個數變成二進制形式,然後統計有多少個1。

思路:

於是做法就是把一個數變成二進制形式,然後統計有多少個1。。

代碼:

#include<iostream>
using namespace std;
int main(){
    int n ;
    while( cin >> n ){
        int cnt = 0 ;
        while( n ){
            if( n & 1 )
                cnt ++ ;
            n >>= 1 ;
        }
        cout << cnt << endl ;
    }
    return 0;
}

B - Finding Team Member

題意:

有2n個人,輸入2n個人兩兩組隊的(n+1)(n+2)/2種情況的得分,要求每個組成的小隊分都儘可能的高,輸出組隊方案。

思路:

由於得分唯一,把得分映射到組隊情況,然後將所有組隊情況按得分排序,然後掃一遍就出結果了。

代碼:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#define cls( x ) memset(x,0,sizeof(x)) 
#define mp make_pair
using namespace std;

typedef long long lint;

const int maxn = 402 ;
int cnt[maxn*maxn*5] , vis[ 5 * maxn ] , te[maxn * 5];
map<int , pair<int , int> > has ;
int main(){
    //freopen("input.txt","r",stdin);
    int n ;
    while( cin >> n ){
        has.clear() ;
        int k = 0 ;
        for( int i = 2 ; i <= 2 * n ; i++ ){
            for( int j = 1 ; j <= i - 1 ; j++ ){
                cin >> cnt[k] ;
                has[cnt[k]] = mp( i , j ) ;
                k++ ;
            }
        }
        cls( vis ) ;
        sort( cnt , cnt + k ) ;
        for( int i = k - 1 ; i >= 0 ; i-- ){
            pair<int , int>p = has[cnt[i]] ;
            if( !vis[p.first] && !vis[p.second] )
                te[p.first] = p.second , te[p.second] = p.first ;
            else
                continue ;
            vis[p.first] = 1 ;
            vis[p.second] = 1 ;
        }
        for( int i = 1 ; i <= 2 * n ; i++ )
            cout << te[i] << ' ' ;
        cout << endl ;
    }
    return 0;
}

C - A Problem about Polyline

題意:

輸入一個點座標,求經過該點的一個折線函數最小x。

思路:

通過帶入斜率爲1這個特點,可以得到如下式子:
k=\frac{a-b}{2x},\frac{a+b}{2x}

k=ab2x,a+b2x

x=\frac{a-b}{2k},\frac{a+b}{2k}
x=ab2k,a+b2k

所以x要小則k要儘量大,又因爲 x>=bx>=b 帶入 x=bx=b 得到:
k=\lfloor\frac{a-b}{2b}\rfloor,\lfloor\frac{a+b}{2b}\rfloor
k=ab2b,a+b2b

再帶回去:
x=min(\frac{a-b}{2*\lfloor\frac{a+b}{2b}\rfloor},\frac{a+b}{2*\lfloor\frac{a-b}{2b}\rfloor})
x=min(ab2a+b2b,a+b2ab2b)

顯然,在 a>ba>b 的情況下前者較小,且由於斜率限制,a<ba<b 一定是無解的,所以答案就是 \frac{a-b}{2*\lfloor\frac{a+b}{2b}\rfloor}ab2a+b2b

代碼:

#include<cstdio>
#include<iostream>
using namespace std;
typedef long long lint;

int main(){
    lint a , b ;
    while( cin >> a >> b ){
        double x = a + b ;
        double tmp = ( a - b ) / 2 / b + 1 ;
        tmp *= 2 ;
        x /= tmp ;
        if( a < b  )
            cout << -1 << endl ;
        else
            printf( "%.12f\n" , x ) ;
    }
    return 0;
}

D - “Or” Game

題意:

輸入一些數字,可以將一些數字進行乘以x操作,操作共可以進行k次,求操作完後的這些數字的最大與值 。

思路:

要想與值最大,那麼就必須提升最大值的二進制長度,所以所有操作應該只對一個數進行。
預處理出前綴與值和後綴與值,然後掃描一遍假設a[i]進行k次操作,維護最大值即可。

代碼:

#include<cstdio>
#include<iostream>
using namespace std;
typedef long long lint;

const int maxn = 2 * 1e5 + 50 ;
lint a[maxn] , pre[maxn] , suf[maxn] ;
int main(){
    //freopen("input.txt","r",stdin);
    int n , k , x ;
    while( cin >> n >> k >> x ){
        lint mul = 1 ;
        while( k-- ) mul *= x ;
        for( int i = 0 ; i < n ; i++ )
            scanf( "%I64d" , a + i ) ;
        if( n == 1 ){
            cout << a[0] * mul << endl ;
            continue ;
        }
        pre[0] = a[0] ;
        for( int i = 1 ; i < n ; i++ )
            pre[i] = pre[i-1] | a[i] ;
        suf[n-1] = a[n-1] ;
        for( int i = n - 2 ; i >= 0 ; i-- )
            suf[i] = suf[i+1] | a[i] ;
        lint ans = ( a[0] * mul ) | suf[1] ;
        for( int i = 1 ; i < n ; i++ )
            ans = max( ans , pre[i-1] | ( a[i] * mul ) | suf[i+1] ) ;
        cout << ans << endl ;
    }
    return 0;
}

E - Weakness and Poorness

題意:

輸入一些數字.s(i,j)=jk=i(akx),max1ijn|s(i,j)|

思路:

s(i,j)=,ans  k=ij(akx),=max1ijn|s(i,j)|=max1ijnmax( s(i,j) , s(i,j) )=max(max1ijns(i,j) ,max1ijns(i,j) )=max( f(x) , g(x) )

由於f(x)關於x單調遞減,g(x)關於x單調遞增,所以這是一個凸性函數,可以三分求得極值。

代碼:

/*
* @author FreeWifi_novicer
* language : C++/C
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue>

using namespace std;

#define clr( x , y ) memset(x,y,sizeof(x))
#define cls( x ) memset(x,0,sizeof(x))
#define pr( x ) cout << #x << " = " << x << endl 
#define pri( x ) cout << #x << " = " << x << " " 
#define mp make_pair
#define pb push_back
typedef long long lint;
typedef long long ll;
typedef long long LL;

const int maxn = 2e5 + 50 ;
int a[maxn] ;
int n ;
double calc( double x ){
    double ma = 0 , mi = 0 , sum = 0 , res = 0 ;
    for( int i = 0 ; i < n ; i++ ){
        sum += a[i] - x ;
        mi = min( mi , sum )  ;
        ma = max( ma , sum )  ;
        res = max( res , max( ma - sum , sum - mi ) ) ;
    }
    return res ;
}
double ts(){
    double l = -1e5 - 10 , r = 1e5 + 10 ;
    for( int i = 0 ; i < 120 ; i++ ){
        double m1 = ( l + l + r ) / 3.0 , m2 = ( l + r + r ) / 3.0 ;
        if( calc( m1 ) < calc( m2 ) )
            r = m2 ;
        else
            l = m1 ;
    }
    return calc( ( l + r ) / 2 ) ;
}
int main(){
    //freopen("input.txt","r",stdin);
    while( cin >> n ){
        for( int i = 0 ; i < n ; i++ )
            scanf( "%d" , a + i ) ;
        printf( "%.12f\n" , ts() ) ;
    }
    return 0;
}
發佈了127 篇原創文章 · 獲贊 14 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章