AtCoder Beginner Contest 047
A - Fighting over Candies
签到
#include <bits/stdc++.h>
using namespace std;
int read(){...}
const int N = 1e6+5;
int main(){
int a = read() , b = read() , c = read();
if( a < b ) swap( a , b );
if( a < c ) swap( a , c );
if( a == b + c ) cout << "Yes";
else cout << "No";
return 0;
}
B - Snuke's Coloring 2 (ABC Edit)
如果你会两个矩形求交集的话,这题其实非常简单。
#include <bits/stdc++.h>
using namespace std;
int read(){...}
const int N = 1e6+5;
int main(){
int ax = 0 , ay = 0 , bx = read() , by = read() , n = read();
for( int x , y , t ; n ; n -- ){
x = read() , y = read() , t = read();
if( t == 1 ) ax = max( ax , x );
else if( t == 2 ) bx = min( bx , x );
else if( t == 3 ) ay = max( ay , y );
else by = min( by , y );
}
cout << max( 0 , bx - ax ) * max( 0 , by - ay ) ;
return 0;
}
C - 1D Reversi
相邻且相同的可以合并成一个,题目的操作实际上就可以转化成再序列的两端选择一个删除,题目的目标就是希望最后只剩下一个,所以就是求一下将相邻且相同的合并后序列的长度即可。
#include <bits/stdc++.h>
using namespace std;
int read(){...}
const int N = 1e6+5;
int main(){
string s;
cin >> s;
int res = -1 , t = -1;
for( auto c : s ){
if( c == 'B' && t != 1 ) t = 1 , res ++;
if( c == 'W' && t != 0 ) t = 0 , res ++;
}
cout << res ;
return 0;
}
D - An Invisible Hand
这题蛮有意思的,题目中的t
是一个诈骗条件,没有用。
然后对于每一个点购入,最优策略就是再之后的最大值时卖出。所以要求一下后缀最大值,有了后缀最大值就可以\(O(n)\)求出每一个位置的最优策略,整体最优解的方案数。
因为题目保证了原序列不会重复(赛时一开始没看到),所以不存在改变一个值减少大于一个最优解的情况,所以最优解的方案数就是我们要花费的最小代价。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
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;
}
const int N = 1e5+5;
ll a[N] , b[N] , n , res = 0 , vl;
int main(){
n = read() , read();
for( int i = 1 ; i <= n ; i ++ ) a[i] = b[i] = read();
for( int i = n-1 ; i >= 1 ; i -- ) b[i] = max( b[i] , b[i+1] );
for( int i = 1 , t ; i < n ; i ++ ){
t = b[i+1] - a[i];
if( t > vl ) vl = t , res = 1;
else if( t == vl ) res ++;
}
cout << res;
return 0;
}