One Bamboo Contest Round #12(Clone from 2020 ICPC Shenyang)
G. The Witchwood
签到
#include <bits/stdc++.h>
#define int long long
using namespace std;
int read(){
int x = 0 , ch = getchar();
while( ch < '0' || ch > '9' ) ch = getchar();
while( ch >= '0' && ch <= '9' ) x = x * 10 + ch - '0' , ch = getchar();
return x;
}
int32_t main(){
int n = read() , m = read();
vector<int> a(n);
for( auto & i : a ) i = read();
std::sort(a.begin(), a.end(),greater<int>());
int res = 0;
for( int i = 0 ; i < m ; i ++ )
res += a[i];
cout << res << "\n";
return 0;
}
F. Kobolds and Catacombs
题目的意思是,把序列尽可能的划分成多个子区间,要求对子区间排序后整个序列有序。
首先设第\(j\)个区间为\([l_j,r_j]\),由此可知\(l_1=1,l_j = r_{j-1}+1\),并且每个区间应该满足\([l_j,r_j]\)中的最大值小于\([r_j+1,n]\)中的最小值。
所以先计算出后缀最小值,然后根据后缀最小值就能找到每个右端点的位置。
#include <bits/stdc++.h>
#define int long long
using namespace std;
int read(){...}
int32_t main(){
int n = read() , cnt = 0;
vector<int> v(n) , b(n);
for( auto & i : v ) i = read();
b[n-1] = v[n-1];
for( int i = n - 2 ; i >= 0 ; i -- ) b[i] = min( v[i] , b[i+1] );
b.push_back(INT_MAX) , v.push_back(INT_MIN) ;
int l = 0;
for( int i = 0 ; i < n && l < n ; i ++ ){
if( v[i] > v[l] ) l = i;
if( b[i+1] >= v[l] ) cnt ++ , l = i+1;
}
cout << cnt << "\n";
return 0;
}
K. Scholomance Academy(补题)
这道题感觉蛮难理解的,最主要的就是那个AUC的积分,其实要求的就是就是样例解释里面阴影部分的面积。
因为数据是离散的,所以可以直接枚举排序后的\(a_i\)作为\(\theta\)的值,如果是阳性TP--
,如果是阴性就要统计答案。
至于题目中定义的几个概念是机器学习中的东西,可以参考这篇博客
#include <bits/stdc++.h>
#define int long long
using namespace std;
struct Node{
bool c;
int s;
Node( bool c = false , int s = 0 ) : c(c) , s(s){};
bool operator < ( Node b ) const {
if( s == b.s ){
if(b.c) return false;
if(c) return true;
}
return s < b.s;
}
};
int32_t main(){
int n , positive = 0 , negative = 0;
cin >> n;
vector<Node> a(n+1);
for( int i = 1 ; i <= n ; i ++ ){
char c;
cin >> c >> a[i].s;
a[i].c = (c == '+');
if( a[i].c ) positive ++;
else negative ++;
}
sort( a.begin()+1 , a.end());
long double res = 0 , tp = positive , cnt = positive * negative;
for( int i = 1 ; i <= n ; i ++ ){
if( a[i].c ) tp --;
else res += tp;
}
cout << fixed << setprecision(9) << res / cnt;
return 0;
}
D. Journey to Un'Goro(补题)
令\(p_i\)表示前\(i\)中有多少个\(r\),则题目要求对于区间\([l,r]\)满足\(p_r-p_{l-1}\)为奇数的区间尽可能的多。
那么则\(p_i\)为奇数的个数和为偶数的个数越接近越多,最多的情况就是各一半。注意的是\(i\)的取值是\([0,n]\)共\(n+1\)个。
那么用搜索枚举出前100种情况就好,剪枝如果过程种\(p_i\)为奇数(或为偶数)的个数大于一半就一定不行
#include <bits/stdc++.h>
#define int long long
using namespace std;
int read(){
int x = 0 , f = 1 , ch = getchar();
while( (ch < '0' || ch > '9') && ch != '-' ) ch = getchar();
if( ch == '-' ) f = -1 , ch = getchar();
while( ch >= '0' && ch <= '9' ) x = ( x << 3 ) + ( x << 1 ) + ch - '0' , ch = getchar();
return x * f;
}
vector<char> s;
int cnt = 0 , n , res , ans;
void dfs( int i , int cntEven , int cntOdd , int p ){
if( cntEven > ans || cntOdd > ans ) return;
if( i == n ){
if( abs( cntOdd - cntEven) <= 1 ){
for( auto c : s ) printf("%c",c);
printf("\n");
if( ++ cnt == 100 ) exit(0);
}
return;
}
s[i] = 'b';
dfs( i+1 , cntEven + (p==0) , cntOdd + (p==1) , p );
s[i] = 'r';
dfs( i+1 , cntEven + (p==1) , cntOdd + (p==0) , p^1 );
return;
}
int32_t main(){
cin >> n;
s = vector<char>(n);
ans = (n+2) / 2 , res = ans * ( n+1-ans );
cout << res << "\n";
dfs( 0 , 1 , 0 , 0 );
return 0;
}