25/01/08 백준일지
백준 문제풀이
32715
처음 읽고 든 생각: 모든 색칠된 좌표를 큐에 넣고 재귀로 해결하면 되지 않을까 생각함. 다만 이러면 시간초과가 확정적이었음
태그를 까보니 Pfx가 있었다. 이게 누적합이라고?라는 생각만 들었는데 곰곰히 생각해보니 pfx로 직선 길이를 쉽게 파악할 수 있음을 깨닳고 바로 코드를 짜서 AC
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <bits/stdc++.h>
using namespace std;
int pfxx[2550][2550];
int pfxy[2550][2550];
int main(){
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n, m; cin >> n >> m;
int k; cin >> k;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
int x; cin >> x;
pfxy[i][j] = pfxy[i - 1][j] + x;
pfxx[i][j] = pfxx[i][j - 1] + x;
}
}
int cnt = 0;
for(int i = k + 1; i <= n - k; i++){
for(int j = k + 1; j <= m - k; j++){
if(pfxx[i][j + k] - pfxx[i][j - k - 1] == k * 2 + 1 && pfxy[i + k][j] - pfxy[i - k - 1][j] == k * 2 + 1) cnt++;
}
}
cout << cnt << "\n";
return 0;
}
23325
처음 읽고 든 생각: 이걸 경우를 어떻게 쪼개야하나…..
태그를 보니 DP가 있었다. 근데 아무리 머리를 굴려봐도 한칸한칸씩 읽어서는 답이 안보였다. 묶어서 경우를 나눠야하나 싶었는데 이게 맞는 접근이었다. 그래서 코드를 짜고 몇번의 오류수정 끝에 AC
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <bits/stdc++.h>
using namespace std;
int dp[200200];
int conv(char c){
if(c == '+') return 10;
else return 1;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
string s; cin >> s;
fill(dp, dp + 200200, -(1<<30));
dp[0] = conv(s[0]);
if(s[0] == '+' && s[1] == '-'){
dp[1] = 11;
}
for(int i = 2; i < s.size(); i++){
if(s[i - 1] == '+') dp[i] = max(dp[i], dp[i - 2] + conv(s[i]));
else dp[i] = max(dp[i], dp[i - 2] - conv(s[i]));
if(i == 2) continue;
if(s[i] == '-' && s[i - 1] == '+'){
if(s[i - 2] == '+') dp[i] = max(dp[i], dp[i - 3] + 11);
else dp[i] = max(dp[i], dp[i - 3] - 11);
}
}
cout << dp[s.size() - 1];
return 0;
}
24892
수학 + 모듈러 연산 문제
최댓값이 되는 경우는 등간격으로 쪼갤 때가 최댓값이 된다.(by 직관)
고등학생때 배웠던 이차함수의 넓이공식을 잘 이용하여 식을 세우자
모듈러 역원에 대하여 공부를 좀 더 해야겠다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <bits/stdc++.h>
#define ll long long
#define mod 1000000007
using namespace std;
ll power_mod(ll a, ll b){
ll res = 1;
a %= mod;
while(b > 0){
if(b & 1LL) res = (res * a) % mod;
a = a * a % mod;
b >>= 1LL;
}
return res;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
ll n, a, b; cin >> n >> a >> b;
ll dif = b - a;
ll sum = (pow(n, 3) - n) * pow(dif, 3);
ll dow = pow(n , 3) * 6;
ll tmp = gcd(sum, dow);
sum /= tmp; dow /= tmp;
cout << (sum * power_mod(dow, mod - 2)) % mod;
return 0;
}
17943
간단한 누적합 XOR 문제
0 xor n = n을 떠올리고 누적합 배열을 만들고 잘 풀어보자
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n, q; cin >> n >> q;
vector<int> pfx(n);
for(int i = 1; i < n; i++){
cin >> pfx[i];
pfx[i] ^= pfx[i - 1];
}
while(q--){
int ca; cin >> ca;
if(ca){
int a, b, c; cin >> a >> b >> c;
int ans = pfx[b - 1] ^ pfx[a - 1] ^ c;
cout << ans << "\n";
}else{
int a, b; cin >> a >> b;
int ans = pfx[b - 1] ^ pfx[a - 1];
cout << ans << "\n";
}
}
return 0;
}
14907
분명 단순한 위상정렬 + 메모이제이션 문제일줄 알고 싱글벙글 들어갔는데….. 입출력이 시간을 이리 잡아먹을줄..
대신 지식이 늘었습니다. c++에서도 구분자를 기준으로 슬라이싱이 가능하네요
이문제는 분명 입출력때문에 골드2인게 틀림없습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <bits/stdc++.h>
#define pii pair<int,int>
using namespace std;
vector<int> adj[26];
vector<int> deg(26);
vector<int> iadj[26];
vector<int> dp(26);
vector<int> cost(26);
int ch(char n){
return n - 'A';
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
string s; queue<int> q;
while(getline(cin, s)){
vector<string> tmp;
stringstream ss(s);
string t;
while(getline(ss, t, ' ')) tmp.push_back(t);
cost[ch(tmp[0][0])] = stoi(tmp[1]);
if(tmp.size() == 2){
q.push(ch(tmp[0][0]));
dp[ch(tmp[0][0])] = stoi(tmp[1]);
}else{
for(char c : tmp[2]){
adj[ch(c)].push_back(ch(tmp[0][0]));
deg[ch(tmp[0][0])]++;
iadj[ch(tmp[0][0])].push_back(ch(c));
}
}
}
while(q.size()){
int u = q.front(); q.pop();
for(auto v : adj[u]){
deg[v]--;
if(deg[v] == 0){
for(auto i : iadj[v]){
dp[v] = max(dp[v], dp[i]);
}
dp[v] += cost[v];
q.push(v);
}
}
}
cout << *max_element(dp.begin(), dp.end());
return 0;
}
This post is licensed under CC BY 4.0 by the author.