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}
x=\frac{a-b}{2k},\frac{a+b}{2k}
所以x要小則k要儘量大,又因爲 x>=b
k=\lfloor\frac{a-b}{2b}\rfloor,\lfloor\frac{a+b}{2b}\rfloor
再帶回去:
x=min(\frac{a-b}{2*\lfloor\frac{a+b}{2b}\rfloor},\frac{a+b}{2*\lfloor\frac{a-b}{2b}\rfloor})
顯然,在 a>b
代碼:
#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(ak−x),求max1≤i≤j≤n|s(i,j)|
思路:
由於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;
}