Codeforces Round #521 (Div. 3) A 模擬 B 貪心 C模擬 D 二分 E 二分+排序
阿新 • • 發佈:2018-12-22
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 ;
}