Atcoder Beginner Contest 243 部分題解
阿新 • • 發佈:2022-03-14
Atcoder Beginner Contest 243 部分題解
A - Shampoo
有一個容積為V
的水箱,每天有F
、M
、T
三個人用水,分別用a、b、c的水,在不加水的情況下誰先不夠用
先取模,然後逐個判斷就好
#include<bits/stdc++.h> using namespace std; int main() { int v , a , b , c ; cin >> v >> a >> b >> c ; if( v >= a + b + c ) v %= (a+b+c); if( v >= a ) v-= a; else { cout << "F"; return 0; } if( v >= b ) v -= b; else{ cout << "M"; return 0; } cout << "T"; return 0; }
B - Hit and Blow
給定長度為n的兩個數列,問有多少個\(a_i=b_i\),問有多少個既在a中又在b中,且位置不同
把a放在集合中,讀入b的時候判讀就好了
#include<bits/stdc++.h> using namespace std; const int N = 1005; int n , a[N] , b[N] , cnt1 , cnt2; set<int> c; inline 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; } int main() { n = read(); for( int i = 1 ; i <= n ; i ++ ) a[i] = read() , c.insert(a[i]); for( int i = 1 , x ; i <= n ; i ++ ) { x = read(); if( a[i] == x ) cnt1 ++; else if( c.count(x) ) cnt2 ++; } cout << cnt1 << '\n' << cnt2 << endl; return 0; }
C - Collision 2
在一個網格圖給出每個人的位置的行進方向(只有左右),只要有人對向而行就會相撞,問是否有人相撞
首先要把行數雜湊一下,動態的維護每一行向左的最有和向右的最左,每次判斷一下就好
#include<bits/stdc++.h> using namespace std; const int N = 2e5+5; int n , xd[N] , yd[N] , l[N] , r[N] ; string s; inline 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; } int main() { n = read(); for( int i = 1 ; i <=n ; i ++ ) yd[i] = read() , xd[i] = l[i] = read() ; sort( l + 1 , l+1+n ); for( int i = 1 ; i <= n ; i ++ ) xd[i] = lower_bound( l+1 , l+1+n , xd[i] ) -l; for( int i = 1 ; i <= n ; i ++ ) l[i] = -1 , r[i] = 0x7f7f7f7f; cin >> s; for( int i = 1 ; i <= n ; i ++ ) { if( s[i-1] == 'L' ) { if( r[ xd[i] ] < yd[i] ) printf("Yes\n") , exit(0); l[ xd[i] ] = max( l[xd[i]] , yd[i] ); } else{ if( l[xd[i]] > yd[i] ) printf("Yes\n") , exit(0); r[ xd[i] ] = min( r[xd[i]] , yd[i] ); } } printf("No\n"); return 0; }
D - Moves on Binary Tree
在一個滿二叉樹上,給定初始位置,有x次操作,U
移動到父親節點L
移動到左兒子R
移動到右兒子
問x次操作後在哪裡,如果直接做的話回到導致溢位,如果先移動到兒子在移動到父親是無效的,所以可以在原操作序列中用U
抵消前面的L
或R
,抵消後在操作就好了
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 2e5+5;
ll n , m ;
string s;
vector<char> t;
int main()
{
cin >> m >> n >> s;
for( auto it : s )
{
if( it == 'U' )
{
if( t.size() && *t.rbegin() != 'U' )
t.pop_back();
else t.push_back('U');
}
else t.push_back( it );
}
for( auto it : t )
{
if( it == 'U' )
n >>= 1;
else if( it == 'L' )
n <<= 1;
else n <<= 1 , n |= 1;
}
cout << n << endl;
return 0;
}
E - Edge Deletion
給一個無向圖,問最多刪除條邊後所有點之間的最短路不變
首先要做多源最短路,自然而然就是Floyed,在做FLoyed的過程中如果存在一條邊可以被替換掉就說明這條邊可以被刪除
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 305 , M = 45005 , inf = 0x7f7f7f7f;
ll n , m , dis[N][N] , u[N] , v[N] , w[N] , cnt , vis[N][N];
inline 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;
}
int main()
{
n = read() , m = read();
for( int i = 1 ; i <= n ; i ++ )
for( int j = 1 ; j <= n ; j ++ )
dis[i][j] = inf;
for( int i = 1 , u , v , w ; i <= m ; i ++ )
u = read() , v = read() , w = read() , dis[u][v] = dis[v][u] = w , vis[u][v] = vis[v][u] = 1;
for( int k = 1 ; k <= n ; k ++ )
for( int i = 1 ; i <= n ; i ++ )
for( int j = 1 ; j <= n ; j ++ )
if( dis[i][j] >= dis[i][k] + dis[k][j] ){
dis[i][j] = dis[j][i] = dis[i][k] + dis[k][j];
if( vis[i][j] ) cnt++ , vis[j][i] = vis[i][j] = 0;
}
cout << cnt << endl;
return 0;
}