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

版权声明:本文为博主原创文章,未经博主允许也可以转载。 https://blog.csdn.net/FrankAx/article/details/84175228

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 ;
}

猜你喜欢

转载自blog.csdn.net/FrankAx/article/details/84175228