AtCoder Beginner Contest 253 A - E
阿新 • • 發佈:2022-05-29
A - Median?
找中間數
#include <iostream> #include <cstdio> #include <algorithm> #include <vector> #include <string> #include <queue> #include <functional> #include <map> #include <set> #include <cmath> #include <cstring> #include <deque> #include <stack> using namespace std; typedef long long ll; #define pii pair<int, int> const ll maxn = 2e5 + 10; const ll inf = 1e17 + 10; int num[maxn]; int main() { for(int i=0; i<3; i++) cin >> num[i]; int a = num[1]; sort(num, num + 3); if(a == num[1]) cout << "Yes" << endl; else cout << "No" << endl; return 0; }
B - Distance Between Tokens
找起點和終點的曼哈頓距離
#include <iostream> #include <cstdio> #include <algorithm> #include <vector> #include <string> #include <queue> #include <functional> #include <map> #include <set> #include <cmath> #include <cstring> #include <deque> #include <stack> using namespace std; typedef long long ll; #define pii pair<int, int> const ll maxn = 2e5 + 10; const ll inf = 1e17 + 10; string s[maxn]; int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n, m; cin >> n >> m; for(int i=0; i<n; i++) cin >> s[i]; int sx = -1, sy, ex, ey; int cnt = 0; for(int i=0; i<n; i++) { for(int j=0; j<m; j++) { if(s[i][j] == 'o') { if(cnt == 0) { sx = i; sy = j; cnt++; } if(cnt == 1) { ex = i; ey = j; } } } } cout << abs(ex - sx) + abs(ey - sy) << endl; return 0; }
C - Max - Min Query
可以直接用 map 維護就好了
我是用 set 維護,然後 map 判斷什麼時候刪除和增加
#include <iostream> #include <cstdio> #include <algorithm> #include <vector> #include <string> #include <queue> #include <functional> #include <map> #include <set> #include <cmath> #include <cstring> #include <deque> #include <stack> using namespace std; typedef long long ll; #define pii pair<int, int> const ll maxn = 2e5 + 10; const ll inf = 1e17 + 10; string s[maxn]; int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int q; cin >> q; set<int>s; map<int, int>vis; while(q--) { int t; cin >> t; if(t == 1) { int x; cin >> x; if(++vis[x] == 1) s.insert(x); } else if(t == 2) { int x, cc; cin >> x >> cc; int way = min(cc, vis[x]); vis[x] -= way; if(vis[x] == 0 && way != 0) s.erase(x); } else { auto it = s.end(); it--; cout << (*it - *s.begin()) << endl; } } return 0; }
D - FizzBuzz Sum Hard
我寫的極其複雜
直接等差數列,減去 a 的倍數,減去 b 的倍數,加上 a 和 b 的公倍數
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
string s[maxn];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
ll n, a, b;
cin >> n >> a >> b;
ll ab = a / __gcd(a, b) * b;
ll t = n / ab;
ll sum = 0;
if(t)
{
sum += (1 + ab) * ab / 2;
sum -= ab * (ab / a - 1) / 2;
sum -= ab * (ab / b - 1) / 2;
sum -= ab;
sum *= t * t;
}
// cout << sum << endl;
if(n % ab)
{
ab = t * ab;
ll ta = (n - ab) / a;
ll tb = (n - ab) / b;
sum -= (ab + a + ab + ta * a) * ta / 2;
sum -= (ab + b + ab + tb * b) * tb / 2;
sum += (1 + ab + n) * (n - ab) / 2;
}
cout << sum << endl;
return 0;
}
E - Distance Sequence
dp
\(dp[i][j]\) 表示第 \(i\) 個數字是 \(j\) 的時候的方案數
狀態轉移:\(dp[i][j] = \sum{}{} dp[i-1][v]\),\(v\) 表示當第 \(i\) 個數字為 \(j\) 時,第 \(i - 1\) 個數字滿足相差絕對值不小於 \(k\) 的數字
純轉移的話複雜度很高,可以考慮用字首和處理一下,複雜度為 \(O(nm)\)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 1010;
const ll inf = 1e17 + 10;
const ll mod = 998244353;
ll dp[maxn][maxn * 5];
ll sum[maxn];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
ll n, m, k;
cin >> n >> m >> k;
for(int i=1; i<=m; i++) {dp[0][i] = 1; sum[i] = sum[i-1] + 1;}
for(int i=1; i<n; i++)
{
for(int j=1; j<=m; j++)
{
ll l = j - k;
ll r = j + k;
l++;
r--;
l = max(1ll, l);
r = min(m, r);
dp[i][j] = (mod + sum[m] - max(0ll, sum[r] - sum[l-1])) % mod;
}
for(int j=1; j<=m; j++)
sum[j] = sum[j-1] + dp[i][j];
// cout << "now: ";
// cout << sum[m] << endl;
}
cout << sum[m] % mod << endl;
return 0;
}
F - Operations on a Matrix
F 到現在都沒過,我的想法是對於每次詢問,找到最近的改變行的操作,然後將那個座標的差值用 map 儲存起來
然後列的疊加還是用樹狀陣列維護,但是現在死活過不去