1. 程式人生 > >Codeforces Round #521 (Div. 3) A 模擬 B 貪心 C模擬 D 二分 E 二分+排序

Codeforces Round #521 (Div. 3) A 模擬 B 貪心 C模擬 D 二分 E 二分+排序

A

Code:

#include <bits/stdc++.h>
#define LL long long 
using namespace std;
int main(){
	int T ;
	cin >> T ;
	int a , b , k ; 
	LL res ; 
	while( T-- ){
		cin >> a >> b >> k ; 
		a -= b ;
		if( k % 2 ){
			k ++ ; 
			k /= 2 ;
			res = 1LL * k * a ; 
			res += b ;
}else{ k /= 2 ; res = 1LL * k * a ; } cout << res << endl; } return 0 ; }

B
思路:每次把右邊1變為0
Code:

#include <bits/stdc++.h>
#define LL long long 
using namespace std;
const int AX = 1e2 + 6 ;
int a[AX] ;
int main(){
	int n ;
	cin >> n ; 
	for( int i = 1 ; i <=
n ; i++ ){ cin >> a[i] ; } int res = 0 ; for( int i = 2 ; i <= n - 1 ; i++ ){ if( !a[i] ){ if( a[i-1] && a[i+1] ){ a[i+1] = 0 ; res ++ ; } } } cout << res << endl; return 0 ; }

C
Code:

#include <bits/stdc++.h>
#define ll long long
using
namespace std; const int AX = 2e5 + 666 ; ll a[AX]; void init(){ } int main() { ll sum = 0LL; std::vector<ll>vec; priority_queue<ll> q; init() ; ios_base::sync_with_stdio(false); cin.tie(0) ; cout.tie(0) ; int n; cin >> n; for(int i = 1; i <= n; i ++){ cin >> a[i] ; sum += a[i] ; q.push( a[i] ) ; } int ans = 0; for( int i = 1; i <= n; i++ ){ if( a[i] == q.top() ){ sum -= a[i]; q.pop(); if( sum == 2 * q.top() ){ vec.push_back(i); ans++; } sum += a[i] ; q.push(a[i]) ; }else{ sum -= a[i]; if( sum == 2 * q.top() ){ vec.push_back(i); ans++; } sum += a[i]; } } cout << ans << endl; for( int i = 0 ; i < vec.size() ; i++ ){ cout << vec[i] << ' ' ; } cout << endl ; return 0; }

D
思路:二分能夠分的塊數,如果最後得到的長度大於等於k就滿足。
Code:

#include <bits/stdc++.h>
using namespace std;
const int AX = 2e5 + 66 ;
int n ; 
int k ; 
int num[AX] ;
bool check( int x ) {
	int ans = 0;
	for(int i = 0; i < AX; i ++){
		if( num[i] ){
			ans += num[i] / x ;
		}
	}
	return ans >= k;
}
int main(){
	int x ; 
	ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0) ; 
	cin >> n >> k ;
	for( int i = 0 ; i < n ; i++ ){
		cin >> x ; 
		num[x] ++ ; 
	}
	int l = 1 , r = n / k ; 
	int maxn = 0 ; 
	while( l <= r ){
		int mid = ( l + r ) >> 1; 
		if( check(mid) ){
			maxn = max( maxn , mid ) ;
			l = mid + 1 ;
		}else r = mid - 1 ;
	}
	int ans = 0 ;
	for( int i = 0 ; i < AX ; i++ ){
		int tmp = num[i] / maxn ;
		for (int j = 0; j < tmp ; ++j ){
			if( k == ans ) break ; 
			cout << i << ' ' ; 
			ans ++ ; 
		}
	}cout << endl ;
	return 0 ; 
}

E
思路:按照出現次數升序排序,然後列舉第一個數大小,每次2倍在陣列中二分查詢比這個數大的第一個數。
Code:

#include <bits/stdc++.h>
#define LL long long 
using namespace std;
const int AX = 2e5 + 66 ;
int a[AX] ; 
map<int,int>mp;
int main(){
	int n ; 
	scanf("%d",&n) ; 
	int x ; 
	for( int i = 0 ; i < n ; i++ ){
		scanf("%d",&x) ;
		mp[x] ++ ; 
	}
	int cnt = 0 ; 
	for( auto t : mp ){
		a[cnt++] = t.second ; 
	}
	LL res = 0 ; 
	sort( a , a + cnt ) ; 
	for( int i = 1 ; i <= a[cnt-1] ; i++ ){
		int tmp = i ;
		LL temp = i ;  
		int st = lower_bound( a , a + cnt , tmp ) - a ; 
		while(1){
			if( st + 1 >= cnt ) break; 
			int pos = lower_bound( a + st + 1 , a + cnt , 2 * tmp ) - a ;
			if( pos < 0 || pos >= cnt ) break ; 
			temp += 2 * tmp ; 
			tmp *= 2 ; 
			st = pos ; 
		}
		res = max( res , temp ) ; 
	}
	cout << res << endl;
	return 0 ;
}