A - Good morning
#include <bits/stdc++.h>
using namespace std;
int32_t main() {
int a , b , c , d;
int ta , ao;
cin >> a >> b >> c >> d;
ta = a * 60 * 60 + b * 60;
ao = c * 60 * 60 + d * 60 + 1 ;
if( ta < ao ) printf("Takahashi\n");
else printf("Aoki\n");
return 0;
}
B - Mex
#include <bits/stdc++.h>
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;
}
int32_t main() {
int n = read();
vector<int> a(2005);
for( int x ; n ; n -- ) x = read() , a[x] ++;
for( int i = 0 ; i <= 2001 ; i ++ )
if( a[i] == 0 ) return cout << i , 0;
return 0;
}
C - Choose Elements
#include <bits/stdc++.h>
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;
}
int32_t main() {
int n = read(), k = read();
vector<int> a(n), b(n);
for (int &i: a) i = read();
for (int &i: b) i = read();
vector<array<int, 2> > f(n);
f[0][1] = f[0][0] = 1;
for (int i = 1; i < n; i++) {
if( f[i-1][1] + f[i-1][0] == 0 ) break;
if (f[i - 1][0]) {
if (abs(a[i] - a[i - 1]) <= k) f[i][0] = 1;
if (abs(b[i] - a[i - 1]) <= k) f[i][1] = 1;
}
if (f[i - 1][1]) {
if (abs(a[i] - b[i - 1]) <= k) f[i][0] = 1;
if (abs(b[i] - b[i - 1]) <= k) f[i][1] = 1;
}
}
if( f[n-1][0] || f[n-1][1] ) cout << "Yes\n";
else cout << "No\n";
return 0;
}
D - Polynomial division
多项式除法,列一个数式,手模一下就有了
#include <bits/stdc++.h>
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;
}
#define mp make_pair
int32_t main() {
int n = read(), m = read();
vector<int> a(n + 1), b(m + 1), c(n + m + 1);
for (auto &i: a) i = read();
for (auto &i: c) i = read();
for( int i = m ; i >= 0 ; i -- ){
b[i] = c[i+n] / a[n];
for( int j = 0 ; j < n ; j ++ )
c[i+j] -= b[i] * a[j];
}
for( int i = 0 ; i <= m ; i ++ )
printf("%d " , b[i] );
return 0;
}
E - Wrapping Chocolate
把盒子和巧克力豆按照宽度从大到小排序,然后开始枚举巧克力,首先把所有宽度大于当前巧克力的盒子的长度都加入到set
中,然后把大于等当前巧克力长度的最小盒子删掉,如果删不掉就输出No
#include <bits/stdc++.h>
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;
}
int32_t main() {
int n = read(), m = read();
vector<pair<int, int>> a(n), b(m);
for (int i = 0; i < n; i++) a[i].first = read();
for (int i = 0; i < n; i++) a[i].second = read();
for (int i = 0; i < m; i++) b[i].first = read();
for (int i = 0; i < m; i++) b[i].second = read();
sort(a.begin(), a.end(), greater<pair<int, int>>());
sort(b.begin(), b.end(), greater<pair<int, int>>());
multiset<int> st;
for( int i = 0 , j = 0 ; i < n ; i ++ ){
while( j < m && a[i].first <= b[j].first ) st.insert(b[j].second) , j ++;
if( st.empty() ) return cout << "No" , 0;
auto it = st.lower_bound(a[i].second);
if( it == st.end() ) return cout << "No" , 0;
st.erase(it);
}
cout << "Yes";
return 0;
}
F - Endless Walk
实际上就是问有多少个点可以走到环上,首先出度为 0 的点,一定走不到环上,其次是只能走到这些出度为 0 的点也是不行的。这个过程和拓扑排序很接近,所以做法就是反向建边,然后跑一遍拓扑排序,没有删掉的点就是答案。
#include <bits/stdc++.h>
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;
}
int32_t main() {
int n = read(), m = read() , res = n;
vector<vector<int> > e(n + 1);
vector<int> deg(n+1);
for( int u , v ; m ; m -- ){
u = read() , v = read() , deg[u] ++ , e[v].push_back(u);
}
queue<int> q;
for( int i = 1 ; i <= n ; i ++ )
if( deg[i] == 0 ) q.push(i);
while( !q.empty() ){
auto u = q.front(); q.pop();
res --;
for( auto v : e[u] ){
deg[v] --;
if( deg[v] == 0 ) q.push(v);
}
}
cout << res << "\n";
return 0;
}
G - Foreign Friends
其实最简单的想法肯定是按照颜色分类,然后跑最短路,然后统计答案。
答案最短路次短路还是太难了,抄了抄 dls 的做法。
做法就是按照二进制位吧颜色进行分类,然后跑多远最短路,更新二进制位不同的点的答案。按照二进制位分类的话最多只有 30 多种情况,很快就跑完了。
#include<bits/stdc++.h>
using namespace std;
#define int long long
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;
}
int32_t main() {
int n = read(), m = read(), k = read(), l = read();
vector<int> a(n + 1);
for (int i = 1; i <= n; i++) a[i] = read();
vector<int> b(l + 1);
for (int i = 1; i <= l; i++) b[i] = read();
vector<vector<pair<int, int> > > e(n + 1);
vector<int> res(n + 1, LLONG_MAX);
for (int u, v, w; m; m--) {
u = read(), v = read(), w = read();
e[u].emplace_back(v, w), e[v].emplace_back(u, w);
}
for (int bit = 0; bit <= ceil(log2(k)); bit++) {
for (int t = 0; t < 2; t++) {
vector<int> dis(n + 1, LLONG_MAX);
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
vector<bool> vis(n+1 , false);
for (auto i: b)
if (((a[i] >> bit) & 1) == t)
dis[i] = 0, q.emplace(0, i);
while (!q.empty()) {
auto [d, u] = q.top();
q.pop();
if( vis[u] ) continue;
vis[u] = true;
for( auto [ v , w ] : e[u] ){
if( dis[v] > d + w ) dis[v] = d + w , q.emplace( dis[v] , v );
}
}
for( int i = 1 ; i <= n ; i ++ ){
if( ((a[i]>>bit)&1) == 1-t)
res[i] = min( res[i] , dis[i] );
}
}
}
for( int i = 1 ; i <= n ; i ++ )
printf("%lld " , (res[i] == LLONG_MAX ? -1 : res[i]) );
return 0;
}
- Beginner AtCoder Contest 245beginner atcoder contest 245 contest programming beginner atcoder beginner atcoder contest 296 beginner atcoder contest 295 beginner atcoder contest abcde beginner atcoder contest 335 beginner atcoder contest 328 beginner atcoder contest 334 beginner atcoder contest 332 beginner atcoder contest 315