• init 만 보면 된다.
  • 받는 배열의 index는 1부터 시작한다.
  • 여기서 init안의 left는 0부터 시작하므로 받는 배열의 0번에는 0이 저장되어 있는데 init 함수가 재귀로 돌면서 이 값까지 처리한다. 
  • query로 찾을 때 답에는 영향이 없는데 최상위 노드에는 0이 저장된다. 
  • 이경우 left를 1로 바꾸면 최상위 노드가 5가된다. 

  • segment트리는 힙처럼 왼쪽 맨 아래부터 채워지는 게 아니라 다른 방식으로 채워진다. 





#include <iostream>
#include <algorithm>
#include <vector>
#include <limits>
using namespace std;
struct RMQ {
        int n;
        vector<int> rangeMin;
        RMQ(const vector<int>& arr) {
               n = arr.size();
               rangeMin.resize(4 * n);
               init(arr, 0, n - 1, 1);
        }
        int init(const vector<int>& arr, int left, int right, int node) {
               if (left == right) {
                       return rangeMin[node] = arr[left];
               }
               int mid = (left + right) / 2;
               int leftMin = init(arr, left, mid, 2 * node);
               int rightMin = init(arr, mid + 1, right, 2 * node + 1);
               return rangeMin[node] = min(leftMin, rightMin);
        }
        int query(int left, int right, int node, int nodeLeft, int nodeRight) {
               if (right < nodeLeft || left > nodeRight) {
                       return INT32_MAX;
               }
               if (left <= nodeLeft && right >= nodeRight) {
                       return rangeMin[node];
               }
               int mid = (nodeLeft + nodeRight) / 2;
               int leftbaby = query(left, right, node * 2, nodeLeft, mid);
               int rightbaby = query(left, right, node * 2 + 1, mid + 1, nodeRight);
               return min(leftbaby, rightbaby);
        }
        int query(int left, int right) {
               return query(left, right, 1, 0, n - 1);
        }
        int update(int index, int newValue, int node, int nodeLeft, int nodeRight) {
               //index가 범위와 관계없을 경우
               if (index < nodeLeft || index > nodeRight) {
                       return rangeMin[node];
               }
               //리프까지 내려온 경우
               if (nodeLeft == nodeRight) {
                       return rangeMin[node] = newValue;
               }
               int mid = (nodeLeft + nodeRight) / 2;
               int a = update(index, newValue, 2 * node, nodeLeft, mid);
               int b = update(index, newValue, 2 * node + 1, mid + 1, nodeRight);
               return rangeMin[node] = min(a, b);
        }
        int update(int index, int newValue) {
               return update(index, newValue, 1, 0, n - 1);
        }
};
int main(void) {
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);
        int n, m;
        cin >> n >> m;
        vector<int> input(n+1);
        for (int i = 1; i <= n; ++i) {
               cin >> input[i];
        }
        RMQ myRMQ(input);
        int cnt = 1;
        int first_2 = 2;
        //for (int i = 1; i < myRMQ.rangeMin.size(); ++i) {
        //      
        //      cout << myRMQ.rangeMin[i] << ' ';
        //      cnt++;
        //      if (cnt == first_2) {
        //             cout << endl;
        //             first_2 *= 2;
        //      }
        //}
        int a, b;
        
        for (int i = 0; i < m; ++i) {
               cin >> a >> b;
               cout << myRMQ.query(a, b) << '\n';
        }
        return 0;
}



#include <iostream>
#include <algorithm>
#include <vector>
#include <limits>
using namespace std;
struct RMQ {
        int n;
        vector<int> rangeMin;
        RMQ(const vector<int>& arr) {
               n = arr.size();
               rangeMin.resize(4 * n);
               init(arr, 0, n - 1, 1);
        }
        int init(const vector<int>& arr, int left, int right, int node) {
               if (left == right) {
                       return rangeMin[node] = arr[left];
               }
               int mid = (left + right) / 2;
               int leftMin = init(arr, left, mid, 2 * node);
               int rightMin = init(arr, mid + 1, right, 2 * node + 1);
               return rangeMin[node] = min(leftMin, rightMin);
        }
        int query(int left, int right, int node, int nodeLeft, int nodeRight) {
               if (right < nodeLeft || left > nodeRight) {
                       return INT32_MAX;
               }
               if (left <= nodeLeft && right >= nodeRight) {
                       return rangeMin[node];
               }
               int mid = (nodeLeft + nodeRight) / 2;
               int leftbaby = query(left, right, node * 2, nodeLeft, mid);
               int rightbaby = query(left, right, node * 2 + 1, mid + 1, nodeRight);
               return min(leftbaby, rightbaby);
        }
        int query(int left, int right) {
               return query(left, right, 1, 0, n - 1);
        }
        int update(int index, int newValue, int node, int nodeLeft, int nodeRight) {
               //index가 범위와 관계없을 경우
               if (index < nodeLeft || index > nodeRight) {
                       return rangeMin[node];
               }
               //리프까지 내려온 경우
               if (nodeLeft == nodeRight) {
                       return rangeMin[node] = newValue;
               }
               int mid = (nodeLeft + nodeRight) / 2;
               int a = update(index, newValue, 2 * node, nodeLeft, mid);
               int b = update(index, newValue, 2 * node + 1, mid + 1, nodeRight);
               return rangeMin[node] = min(a, b);
        }
        int update(int index, int newValue) {
               return update(index, newValue, 1, 0, n - 1);
        }
};
int main(void) {
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);
        int n, m;
        cin >> n >> m;
        vector<int> input(n+1);
        vector<int> input2(n + 1);
        for (int i = 1; i <= n; ++i) {
               cin >> input[i];
               input2[i] = -input[i];
        }
        RMQ myRMQ(input);
        RMQ myRMQ2(input2);
        int cnt = 1;
        int first_2 = 2;
        //for (int i = 1; i < myRMQ.rangeMin.size(); ++i) {
        //      
        //      cout << myRMQ.rangeMin[i] << ' ';
        //      cnt++;
        //      if (cnt == first_2) {
        //             cout << endl;
        //             first_2 *= 2;
        //      }
        //}
        int a, b;
        
        for (int i = 0; i < m; ++i) {
               cin >> a >> b;
               cout << myRMQ.query(a, b) << ' ' << -myRMQ2.query(a,b) << '\n';
        }
        return 0;
}

  • 큰 정수를 순서대로 사용하고 싶으면 map으로 300 -> 0 번 index 이렇게 할 수 있다.
  • 하는 방법은
arr[0] = 300;
map<int,int> myMap;
myMap[300] = 0;

...

int arridx = myMap[300];
cout << arr[arridx];

  • BIT에서 구간합 구하는 핵심 코드
myTree.sum(n) - myTree.sum(idxB);


#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;
//펜윅 트리의 구현, 가상의 배열 A[]의 부분합을
//빠르게 구현할 수 있도록 한다. 초기화시에는 A[]의
//원소가 전부 0이라고 생각한다.
typedef long long ll;
struct FenwickTree {
        vector<ll> tree;
        FenwickTree(ll n) : tree(n + 1) {}
        ll sum(ll pos) {
               ++pos;
               ll ret = 0;
               while (pos > 0) {
                       ret += tree[pos];
                       pos &= (pos - 1);
               }
               return ret;
        }
        void add(ll pos, ll val) {
               ++pos;
               while (pos < tree.size()) {
                       tree[pos] += val;
                       pos += (pos & -pos);
               }
        }
};
int main(void) {
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);
        ll n, m, k;
        cin >> n;
        vector<ll> arr1(n);
        map<ll, ll> B;
        for (int i = 0; i < n; ++i) {
               cin >> arr1[i];
        }
        ll temp;
        for (int i = 0; i < n; ++i) {
               cin >> temp;
               B[temp] = i;
        }
        FenwickTree myTree(1000001);
        ll cnt = 0;
        for (int i = 0; i < n; ++i) {
               int valA = arr1[i];
               int idxB = B[valA];
               cnt += myTree.sum(n) - myTree.sum(idxB);
               myTree.add(idxB, 1);
        }
        cout << cnt << endl;
        
        return 0;
}

//백준 1005
// 만들어야 하는 건물 에서 dfs 해서 제일 시간 오래 걸리는 곳 까지 탐색
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
int fb;//final building
int bt[1010]; //build time
//vector<int> adj[1010];
vector<int> jda[1010];
int dp[1010];
bool ch_fb = false;
bool visited[1001];
vector<int> order;
int dfs(int x) {
        if (jda[x].size() == 0) {
               return bt[x];
        }
        int& ret = dp[x];
        if (ret != -1) {
               return ret;
        }
        ret = 0;
        int N_idx;
        for (N_idx = 0; N_idx < jda[x].size(); ++N_idx) {
               ret = max(dfs(jda[x][N_idx]) + bt[x], ret);
        }
        
        return ret;
}
//위상정렬 포기
//void ddfs(int x) {
//      visited[x] = true;
//      int temp;
//      for (int next = 0; next < adj[x].size(); ++next) {
//             temp = adj[x][next];
//             if (visited[temp] == false) {
//                     dfs(temp);
//             }
//      }
//      order.push_back(temp);
//}
//int a, b;
//void topologicalSort() {
//      int n = a;
//      memset(visited, false, sizeof(visited));
//      order.clear();
//      for (int i = 1; i <= n; ++i) {
//             if (!visited[i]) {
//                     dfs(i);
//             }
//      }
//      reverse(order.begin(), order.end());
//      return ;
//}
int main(void)
{
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);
        int k1, k2;//for input
        int t;
        cin >> t;
        while (t--) {
               for (int i = 0; i < 1010; ++i) {
                       jda[i].clear();
               }
               memset(dp, -1, sizeof(dp));
               memset(bt, -1, sizeof(bt));
               int a, b;
               cin >> a >> b;
               for (int i = 1; i <= a; ++i) {
                       cin >> bt[i];
               }
               for (int i = 0; i < b; ++i) {
                       cin >> k1 >> k2;
                       //adj[k1].push_back(k2);
                       jda[k2].push_back(k1);
               }
               cin >> fb;
               cout << dfs(fb) << '\n';
               
               //for (int i = 1; i <= a; ++i) {
               //      cout << dp[i] << ' ';
               //}
               //cout << "끝" << endl; /*debugging*/
        }
}
bt[next] 를 해주고 첫 노드 방문 처리를 main 해서 해준 게 포인트

//백준 1005
// 만들어야 하는 건물 에서 dfs 해서 제일 시간 오래 걸리는 곳 까지 탐색
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
int fb;//final building
int bt[1010]; //build time
//vector<int> adj[1010];
vector<int> adj[501];
int dp[1010];
bool ch_fb = false;
bool visited[1001];
vector<int> order;
int dfs(int x) {
        int& ret = dp[x];
        if (ret != -1) {
               return ret;
        }
        ret = 0;
        for (int i = 0; i < adj[x].size(); ++i) {
               int next = adj[x][i];
               ret = max(ret,bt[next] + dfs(next));
        }
        return ret;
}
int main(void)
{
        memset(dp, -1, sizeof(dp));
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);
        int t;
        cin >> t;
        int k1=0;//for input
        for(int i=1;i<=t;++i){
               cin >> k1;
               bt[i] = k1;
               while (1) {
                       cin >> k1;
                       if (k1 == -1) {
                               break;
                       }
                       adj[i].push_back(k1);
               }
        }
        
        for (int i = 1; i <= t; ++i) {
               cout << dfs(i) + bt[i] << '\n';
        }
}


//[위상정렬] 백준 2623 음악 프로그램
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
vector<int> adj[1001];
bool visited[1001];
vector<int> order;
void dfs(int x) {
        visited[x] = true;
        for (int i = 0; i < adj[x].size(); ++i) {
               int next = adj[x][i];
               if (!visited[next]) {
                       dfs(next);
               }
        }
        order.push_back(x);
}
int a, b;
vector<int> topo() {
        order.clear();
        memset(visited, false, sizeof(visited));
        for (int i = 1; i <= a; ++i) {
               if(!visited[i])
                       dfs(i);
        }
        reverse(order.begin(), order.end());
        //사이클 확인하는 코드 좀더 효율적으로 짤 필요
        for (int i = 1; i <= a; ++i) {
               int len = adj[i].size();
               for (int j = 0; j < len; ++j) {
                       int aaa = i, bbb = adj[i][j];
                       bool aa = false;
                       for (int k = 0; k < order.size(); ++k) {
                               if (aaa == order[k]) {
                                      aa = true;
                               }
                               if (aa == false && order[k] == bbb) {
                                      return vector<int>();
                               }
                       }
                       aa = false;
               }
        }
               
        return order;
}
int main(void) {
        cin >> a >> b;
        for (int i = 0; i < b; ++i) {
               int aa;
               int bb, cc;
               cin >> aa;
               if (aa == 1) {
                       cin >> aa;//받고 아무것도 안해도 된다.
               }
               else {
                       cin >> bb;
                       for (int j = 0; j < aa-1; ++j) {
                               cin >> cc;
                               adj[bb].push_back(cc);
                               bb = cc;
                       }
               }
        }
        vector<int> ans = topo();
        if (ans.size() == 0) {
               cout << 0;
               return 0;
        }
        for (int i = 0; i < ans.size(); ++i) {
               cout << ans[i] << '\n';
        }
        return 0;
}


// [DFS] 백준 11403 경로찾기
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
int adj[101][101];
int ans[101][101];
bool visited[101];
int n;
bool first_on;
void dfs(int x,int first) {
        if (first == x && first_on) {
               ans[x][x] = 1;
        }
        else {
               first_on = true;
        }
        visited[x] = true;
        for (int i = 1; i <= n; ++i) {
               if ((!visited[i] || first == i) && adj[x][i] == 1) {
                       dfs(i,first);
               }
        }
}
int main(void) {
        cin >> n;
        for (int i = 1; i <= n; ++i) {
               for (int j = 1; j <= n; ++j) {
                       cin >> adj[i][j];
               }
        }
        for (int i = 1; i <= n; ++i) {
               for (int j = 1; j <= n; ++j) {
                       memset(visited, false, sizeof(visited));
                       first_on = false;
                       dfs(i,i);
                       if (visited[j]) {
                               if (i != j) {
                                      ans[i][j] = 1;
                               }
                       }
               }
        }
        for (int i = 1; i <= n; ++i) {
               for (int j = 1; j <= n; ++j) {
                       cout << ans[i][j] << ' ';
               }
               cout << '\n';
        }
        return 0;
}

A. Minimum Binary Number



처음 문제를 봤을 때 operation을 1번이나 제한적으로 쓸 수 있다고 생각해서 A 부터 엄청 어려운 게 나왔구나 했는데 계속 사용이 가능했다. 보면 나올 수 있는 최소의 값은 0의 개수를 세어주고 그 뒤에 1을 붙이거나, input이 1 0 인 예외를 처리해주면 통과되었다. 

#include <iostream>
#include <string>
using namespace std;
char arr[1001];
int main(void) {
       int n;
       cin >> n;
       string s;
       cin >> s;
       if (n == 1 && s[0] == '0') {
               cout << '0' << endl;
               return 0;
       }
       int cnt = 0;
       for (int i = 0; i < n; ++i) {
               if (s[i] == '0') {
                      cnt++;
               }
       }
       cout << '1';
       for (int i = 0; i < cnt; ++i) {
               cout << '0';
       }
       return 0;
}



B. Lara Croft and the New Game


처음 문제를 봤을 때 x좌표와 y좌표를 k,n,m에 대해서 나타낼 수 있을 걸 알았지만 교육적인 목적에서 직접 경로를 탐색하는 코드를 짜보았다. 무슨 생각인 진 모르겠지만 k가 10^9보다 작다고 생각해서 시간초과는 안 날 것이라 생각했는데 짜놓고 제출하고 시간초과가 나서 생각해보니 최악의 경우 INT32_MAX-1까지 가능했다. 20억번이므로 대략 20초가 걸리므로 당연히 시간초과
그래도 구현한 코드를 올려보면 

#include <iostream>
#include <string>
using namespace std;
int c;
int x = 1, y = 1;
bool inturrupt() {
       if (x == 1 && y == 2) {
               cout << x << ' ' << y << endl;
               return 1;
       }
       if (c == 0) {
               cout << x << ' ' << y << endl;
               return 1;
       }
       c--;
       return false;
};
void print() {
       cout << x << ' ' << y << endl;
}
int main(void) {
       int a, b;
       cin >> a >> b >> c;
       a--;
       b--;
       //print();
       if (inturrupt()) {
               return 0;
       }
       
       for (int i = 1; i <= a; ++i) {
               x++;
               if (inturrupt()) {
                      return 0;
               }
               //print();
       }
       for (int i = 1; i <= b; ++i) {
               y++;
               if (inturrupt()) {
                      return 0;
               }
               //print();
       }
       while (c != 0) {
               x--;
               if (inturrupt()) {
                      return 0;
               }
//print();
               for (int i = 1; i <= b - 1; ++i) {
                      y--;
                      if (inturrupt()) {
                              return 0;
                      }
               //     print();
               }
               x--;
               if (inturrupt()) {
                      return 0;
               }
               //print();
               for (int i = 1; i <= b - 1; ++i) {
                      y++;
                      if (inturrupt()) {
                              return 0;
                      }
               //     print();
               }
       }
       return 0;
}

inturrupt 함수는 한번 x나 y를 바꾸는 연산을 한 다음에 실행시켜 줘서 k가 0이 되면 x,y를 출력하고 끝내도록 만들었다. 코드는 엄청 복잡했다. 

#include <iostream>
#include <string>
using namespace std;
int c;
int x = 1, y = 1;
int main(void) {
       int n, m;
       cin >> n >> m >> c;
       if (c < n) {
               cout << 1 + c << ' ' << 1 << endl;
               return 0;
       }
       if (c < n + m - 1) {
               cout << n << ' ' << (c - (n - 1)) + 1 << endl;
               return 0;
       }
       if (n*m - 1 == c) {
               cout << 1 << ' ' << 2 << endl;
               return 0;
       }
       c -= (m + n - 2);
       int temp = n - 1 - ((c-1) / (m - 1));
       int temp2;
       if (temp % 2 == 0) {
               temp2 = 1 + (c-1) % (m - 1);
       }
       else {
               temp2 =  m - 1 - (c-1) % (m - 1);
       }
       cout << temp << ' ' << temp2 + 1 << endl;
       return 0;
}

x와 y를 n,m,k에 대한 식으로 나타내서 짠 코드. 여기서 
Note that k doesn't fit into 32-bit integer type!
이런 문구가 있는 걸 간과했다. long long 으로 작성하면 accept를 받을 수 있었다. 



C. Nested Segments


뻔한 문제 같은데 도저히 풀 방법이 생각나지 않았다. Contest 가 끝나고 나서 코드를 확인해 보니

좌표를 묶어서 first 크기대로 정렬을 한다. first가 같으면 second가 작은 순으로 정렬한다. 

본래 순서의 index를 가지고 있어야 하므로 index배열을 따로 만들고 index배열을 정렬시키면서 정럴시키는 cmp 함수안의 조건은 pair값을 사용한다. 

정렬이 끝나면 첫번째 값은 무조건 다음값에 포함되므로 생각하지 않고 second 값만 비교한다. 

#include <iostream>
#include <algorithm>
using namespace std;
int u[300001];
pair<int, int> in[300001];
int main(void)
{
       int n;
       cin >> n;
       for (int i = 1; i <= n; ++i) {
               u[i] = i;
               cin >> in[i].first >> in[i].second;
       }
       sort(u + 1, u + n + 1, [](int a, int b) {
               if (in[a].first != in[b].first) {
                      return in[a].first < in[b].first;
               }
               else {
                      return in[a].second > in[b].second;
               }
       });
       int temp = u[1];
       for (int i = 2; i <= n; ++i) {
               if (in[temp].second >= in[u[i]].second) {
                      cout << u[i] << ' ' << temp << endl;
                      return 0;
               }
               else {
                      temp = u[i];
               }
       }
       cout << -1 << ' ' << -1 << endl;
       return 0;
}




A. Splits

A 번 문제가 아니었다면 못풀었을 것 같다. 
A라 분명 쉬울껀데 하면서 계속 해보니까 
결국 중요한 건 맨 앞에 오는 숫자의 개수이고 뒤는 1로 다 채워버려도 됐다. 
어떤 숫자가 n이라면

n개를 다 1로 채우는 방법,
n개에서 한개를 2로하고 나머지를 1로 채우는 방법
n개에서 2개를 2로하고 나머지를 1로 채우는 방법

... 

n개에서 n/2개를 2로하고 나머지가 있다면 1로 두는 방법 으로 구할 수 있다.

따라서 모든 방법의 수는 n/2+1

#include <iostream>
using namespace std;
int main(void)
{
       int n;
       cin >> n;
       cout << n / 2 + 1;
       return 0;
}



B. Messages


브루트포스로 풀었다. 

편지를 안 읽고 두냐, 아니면 얼른 읽어버리냐의 최대값의 차이는 

(t-ti)*c + (a-b*(t-ti))

이런 수식으로 구할 수 있었다. ti를 편지를 받은 tb[i] 부터 끝까지 가지고 있는 <= t 로 범위를 준 후 다 해본다음의 max 값을 ans 에 더해줘서 구했다. 

이게 될까 싶었는데 돌려보니 바로 Accept 가 떠서 신기했다. 

#include <iostream>
#include <algorithm>
using namespace std;
int tb1[100001];
int main(void)
{
       int n, a, b, c, t;
       cin >> n >> a >> b >> c >> t;
       for (int i = 0; i<n; ++i) {
              cin >> tb1[i];
       }
       int ans = 0;
       for (int i = 0; i<n; ++i) {
              int tmax = 0;
              for (int ti = tb1[i]; ti <= t; ++ti) {
                     int temp = (t - ti)*c + (a - b * (t - ti));
                     tmax = max(tmax, temp);
              }
              ans += tmax;
       }
       cout << ans << endl;
       return 0;
}






한시간 동안 풀었는데 결국 풀지 못했다. 

[2 3 1]

의 뜻이 뭔지 이해가 안 되었던게 컸던 것 같다. 

처음에 생각했던 것은 tetris 니까 n개의 블록을 잘 내려서 줄을 없애라는 줄 알았다. 

이렇게 하면 1개가 있는 자리에 n개의 블록을 1개씩 보내주면 모두 2개 이상이 되어 두 줄을 없앨 수 있어서 

2가 답인 줄 알았다. 

해석할 때 시간이 오래 걸릴 것 같아 파파고번역기로 번역을 해서 한게 좋지 않은 영향을 준 것 같다. 

실제 문제는 Hack 단계에서 다른 사람의 코드를 보니 3개의 열이 있고 주어진 블록을 해당열에다가 쌓는 형식이었다.

문제만 제대로 이해했으면 금방 풀었을 텐데 아쉽다. 

Accept 받은 코드
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <limits.h>
#include <queue>
#include <stack>
using namespace std;
int tb1[100001];
int che[100001];
bool doo[100001];
int n, m;
int main(void)
{
       cin >> n >> m;
       
       for (int i = 0; i < m; ++i) {
              int k;
              cin >> k;
              tb1[k]++;
       }
       int ans = INT32_MAX;
       for (int i = 1; i <= n; ++i) {
              ans = min(ans, tb1[i]);
       }
       cout << ans << endl;
       return 0;
}



B. Lecture Sleep


주인공은 잠이 많아 수업시간에 조는데 깨어있는 동안은 열심히 적는다. 

단 한번 깨울 수 있는데 깨우면 m분만큼 필기를 한다.

 최대한 많이 필기 하는 양을 출력

#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <limits.h>
#include <queue>
#include <stack>
using namespace std;
int tb1[100001];
bool che[100001];
bool doo[100001];
stack<int> st;
int n, m;
int main(void)
{
       cin >> n >> m;
       
       for (int i = 0; i < n; ++i) {
              cin >> tb1[i];
       }
       int ans = 0;
       for (int i = 0; i < n; ++i) {
              int k;
              cin >> k;
              che[i] = k;
              if (k == 1) {
                     st.push(i);
                     ans += tb1[i];
              }
       }
       
       int tempansmax = 0;
       for (int i = 0; i < n-m+1; ++i) {
              int tempans = ans;
              for (int k = i; k < i + m; ++k) {
                     if (che[k] == 0) {
                           tempans += tb1[k];
                     }
              }
              tempansmax = max(tempansmax, tempans);
       }
       cout << tempansmax << endl;
       return 0;
}

Time Out 날 걸 확신하고 쓴 코드. 
 for (int k = i; k < i + m; ++k) {
                     if (che[k] == 0) {
                           tempans += tb1[k];
                     }
              }
이 코드를 조금 만 더 최적화 하면 될 것 같다. 

바뀌는 부분은 맨 처음과 맨 끝이므로 
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <limits.h>
#include <queue>
#include <stack>
using namespace std;
int tb1[100001];
bool che[100001];
bool doo[100001];
stack<int> st;
int n, m;
int main(void)
{
       cin >> n >> m;
       
       for (int i = 0; i < n; ++i) {
              cin >> tb1[i];
       }
       int ans = 0;
       for (int i = 0; i < n; ++i) {
              int k;
              cin >> k;
              che[i] = k;
              if (k == 1) {
                     st.push(i);
                     ans += tb1[i];
              }
       }
       int tempans = ans;
       int tempansmax = 0;
       for (int k = 0; k < m; ++k) {
              if (che[k] == 0) {
                     tempans += tb1[k];
              }
       }
       for (int i = 1; i < n-m+1; ++i) {
              if (che[i - 1] == 0) {
                     tempans -= tb1[i - 1];
              }
              if (che[i + m - 1] == 0) {
                     tempans += tb1[i + m - 1];
              }
              tempansmax = max(tempansmax, tempans);
       }
       cout << tempansmax << endl;
       return 0;
}
이렇게 수정을 했는데 TC4에서 Wrong answer 이 나왔다. 

int tempans = ans;
       int tempansmax = 0;
       for (int k = 0; k < m; ++k) {
              if (che[k] == 0) {
                     tempans += tb1[k];
              }
       }
       for (int i = 1; i < n-m+1; ++i) {
              if (che[i - 1] == 0) {
                     tempans -= tb1[i - 1];
              }
              if (che[i + m - 1] == 0) {
                     tempans += tb1[i + m - 1];
              }
              tempansmax = max(tempansmax, tempans);
       }

여기서 tempansmax가 for(int i=1 로 들어가기 전에 k=0~m 까지 더한 값을 저장하고 가야 하는데 놔두고 가서 TC4가
k=0에서 시작해서 하는게 최대값인 경우라 Wrong Answer 이었다 보다


Accept 받은 코드
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <limits.h>
#include <queue>
#include <stack>
using namespace std;
int tb1[100001];
int che[100001];
bool doo[100001];
int n, m;
int main(void)
{
       cin >> n >> m;
       
       for (int i = 0; i < n; ++i) {
              cin >> tb1[i];
       }
       int ans = 0;
       for (int i = 0; i < n; ++i) {
              int k;
              cin >> k;
              che[i] = k;
              if (k == 1) {
                     ans += tb1[i];
              }
       }
       int tempans = ans;
       
       for (int k = 0; k < m; ++k) {
              if (che[k] == 0) {
                     tempans += tb1[k];
              }
       }
       int tempansmax = tempans;
       for (int i = 1; i < n-m+1; ++i) {
              if (che[i - 1] == 0) {
                     tempans -= tb1[i - 1];
              }
              if (che[i + m-1] == 0) {
                     tempans += tb1[i + m-1];
              }
              tempansmax = max(tempansmax, tempans);
       }
       cout << tempansmax << endl;
       return 0;
}


+ Recent posts