Wednesday, April 15, 2020

CodeForces. 1337C Linova and Kingdom

1.Problem
https://codeforces.com/contest/1337/problem/C

2.Idea
Sort by {Depth - Child Number}, and pick k vertices.

3.Source
 int n, k;  
 vector<int> adj[N];  
 int dist[N];  
 bool visited[N];  
 int child[N];  
 bool col[N];  
 int dist2[N];  
 struct City {  
      int num, child, dist;  
      bool operator < (const City &a)const {  
           return dist - child < a.dist - a.child;  
      }  
 } Cities[N];  
 void getChild(int k)  
 {  
      //cout << k << endl;  
      visited[k] = true;  
      for (int i = 0; i < adj[k].size(); i++) {  
           int u = adj[k][i];  
           if (visited[u] == 0) {  
                getChild(u);  
                child[k] += (1 + child[u]);  
           }  
      }  
 }  
 void colorCities()  
 {  
      for (int i = 0; i < n; i++) {  
           Cities[i].num = i;  
           Cities[i].child = child[i];  
           Cities[i].dist = dist[i];  
      }  
      sort(Cities, Cities + n);  
      for (int i = 0; i < n - k; i++) {  
           int t = Cities[i].num;  
           col[t] = true;  
      }  
 }  
 int main()  
 {  
      cin >> n >> k;  
      for (int i = 0; i < n - 1; i++) {  
           int u, v;  
           cin >> u >> v;  
           u--; v--;  
           adj[u].push_back(v);  
           adj[v].push_back(u);  
      }  
      // get dist  
      memset(visited, 0, sizeof visited);  
      queue<P> q;  
      q.push(P(0, 0));  
      while (!q.empty()) {  
           int v = q.front().first;  
           int d = q.front().second;  
           q.pop();  
           visited[v] = 1;  
           dist[v] = d;  
           for (int i = 0; i < adj[v].size(); i++) {  
                int u = adj[v][i];  
                if (visited[u] == 0 && dist[u] == 0) {  
                     q.push(P(u, d + 1));  
                }  
           }  
      }  
      //get child  
      memset(visited, 0, sizeof visited);  
      getChild(0);  
      //color  
      colorCities();  
      //count  
      memset(visited, 0, sizeof visited);  
      queue<P> q1;  
      q1.push(P(0, 0));  
      while (!q1.empty()) {  
           int v = q1.front().first;  
           int d = q1.front().second;  
           q1.pop();  
           visited[v] = 1;  
           dist2[v] = d;  
           if (col[v]) d++;  
           for (int i = 0; i < adj[v].size(); i++) {  
                int u = adj[v][i];  
                if (visited[u] == 0) {  
                     q1.push(P(u, d));  
                }  
           }  
      }  
      int ans = 0;  
      for (int i = 0; i < n; i++) {  
           if (col[i] == 0) ans += dist2[i];  
      }  
      cout << ans << endl;  
      return 0;  
 }  

Tuesday, April 14, 2020

CodeForces. 1339D Edge Weight Assignment

1.Problem.
https://codeforces.com/contest/1339/problem/D

2.Idea
Here

3.Source
 vector<int> adj[N];  
 int d[N];  
 set<int> st;  
 // calc dist from root  
 void dfs(int v, int p)  
 {  
      for (auto& x : adj[v]) {  
           if (x == p) continue;  
           d[x] = d[v] + 1;  
           dfs(x, v);  
      }  
 }  
 int main()  
 {  
      int n;  
      cin >> n;  
      for (int i = 1; i < n; i++) {  
           int v, u;  
           cin >> v >> u;  
           adj[u].push_back(v);  
           adj[v].push_back(u);  
      }  
      int root = 0;  
      for (int i = 1; i <= n; i++) {  
           if (adj[i].size() == 1) {  
                root = i;  
                break;  
           }  
      }  
      dfs(root, 0);  
      int mn = 1, mx = n - 1;  
      for (int i = 1; i <= n; i++) {  
           if (adj[i].size() == 1) {  
                if (d[i] % 2 != 0) {  
                     mn = 3;  
                }  
                st.insert(adj[i][0]);  
                --mx;  
           }  
      }  
      mx += st.size();  
      cout << mn << " " << mx << endl;  
      return 0;  
 }  

Sunday, April 12, 2020

POJ.2080 Calendar

1.Problem
http://poj.org/problem?id=2080

2.Idea
Simulate exact date month year

3.Source
 const char wstr[][20] = { "Saturday","Sunday","Monday","Tuesday","Wednesday","Thursday","Friday" };  
 int days_of_year(int year)  
 {  
      if (year % 100 == 0) {  
           return year % 400 == 0 ? 366 : 365;  
      }  
      return year % 4 == 0 ? 366 : 365;  
 }  
 int days_of_month(int month, int year)  
 {  
      if (month == 2)  
           return days_of_year(year) == 366 ? 29 : 28;  
      int d;  
      switch (month)  
      {  
           case 1: case 3: case 5: case 7: case 8: case 10: case 12:   
                d = 31; break;  
           default:  
                d = 30;  
                break;  
      }  
      return d;  
 }  
 int main()  
 {  
      int n;  
      cin >> n;  
      while (n >= 0) {  
           int year, month, day, week;  
           week = n % 7;  
           year = 2000;  
           month = 1;  
           day = 1;  
           while (n) {  
                if (n >= days_of_year(year)) {  
                     n -= days_of_year(year);  
                     year++;  
                }  
                else if(n >= days_of_month(month, year)) {  
                     n -= days_of_month(month, year);  
                     month++;  
                }  
                else {  
                     day += n;  
                     n = 0;  
                }  
           }  
           cout << year << '-' << (month < 10 ? "0" : "") << month << "-" << (day < 10 ? "0" : "") << day << " " << wstr[week] << endl;  
           cin >> n;  
      }  
      return 0;  
 }  

Friday, April 10, 2020

Codeforces.1334C Circle of Monsters

1.Problem
https://codeforces.com/contest/1334/problem/C

2.Idea
Only start point takes a[i] shoots, and other places a[i] - b[i-1]. Check every places as start point.

3.Source
 int n, t;  
 ll a[300005], b[300005], ac[300005];  
 void solve()  
 {  
      ll sum = 0;  
      for (int i = 0; i < n; i++) {  
           ac[i] = max(0ll, a[i] - b[(i + n - 1) % n]);  
           sum += ac[i];  
      }  
      ll ans = 1ll << 60;  
      for (int i = 0; i < n; i++) {  
           ans = min(ans, sum - ac[i] + a[i]);  
      }  
      //cout << ans << endl;  
      printf("%lld\n", ans);  
 }  
 int main()  
 {  
      scanf("%d", &t);  
      while (t--) {  
           scanf("%d", &n);  
           for (int i = 0; i < n; i++) {  
                scanf("%lld%lld", &a[i], &b[i]);  
           }  
           solve();  
      }  
      return 0;  
 }  

Wednesday, April 8, 2020

CodeForces. 1333C Eugene and an array

1.Problem
https://codeforces.com/problemset/problem/1333/C

2.Idea
Keep tracking right most sum zero segment. 

3.Source
 int n;  
 map<ll, int> mp;  
 ll ans, sum;  
 int x, q;  
 int main()  
 {  
      cin >> n;  
      q = -1;  
      mp[0] = 0;  
      for (int i = 1; i <= n; i++)  
      {  
           cin >> x;  
           sum += x;  
           if (mp.count(sum)) {  
                q = max(q, mp[sum]);  
           }  
           ans += (i - q - 1);  
           mp[sum] = i;  
      }  
      cout << ans << endl;  
      return 0;  
 }  

Monday, April 6, 2020

POJ.1019 Number Sequence

1.Problem
http://poj.org/problem?id=1019

2.Idea
Enumeration

3.Source
 #define MAX_N 35000  
 ll a[MAX_N];  
 ll b[MAX_N];  
 int n;  
 int getDigNum(int k)  
 {  
      if (k < 1) return 0;  
      int ans = 0;  
      while (k) {  
           ans++;  
           k /= 10;  
      }  
      return ans;  
 }  
 void solve()  
 {  
      if (n == 1) {  
           cout << 1 << endl;  
           return;  
      }  
      if (n == 2) {  
           cout << 1 << endl;  
           return;  
      }if (n == 3) {  
           cout << 2 << endl;  
           return;  
      }  
      int i1 = 1, i2 = 1;  
      //get group  
      while (b[i1] <= n) i1++;  
      i1--;  
      if (b[i1] == n) {  
           cout << i1 % 10 << endl;  
           return;  
      }  
      else {  
           n = n - b[i1];  
      }  
      //get number  
      while (a[i2] <= n) i2++;  
      i2--;  
      if (a[i2] == n) {  
           cout << i2 % 10 << endl;  
           return;  
      }  
      else {  
           n = n - a[i2];  
      }  
      //get digit  
      int h = i2 + 1;  
      n = getDigNum(h) - n;  
      h = h / (int)pow(10.0, n);  
      cout << h % 10 << endl;  
 }  
 int main()  
 {       
      for (int i = 1; i < MAX_N; i++) {  
           a[i] = a[i - 1] + getDigNum(i);  
           b[i] = b[i - 1] + a[i];  
      }  
      int t = 0;  
      cin >> t;  
      while (t--) {  
           cin >> n;  
           solve();  
      }  
      return 0;  
 }  

Sunday, April 5, 2020

LeetCode 122. Best Time to Buy and Sell Stock II

1.Problem
https://leetcode.com/explore/challenge/card/30-day-leetcoding-challenge/528/week-1/3287/

2.Idea
Just keep adding positive diffs.

3.Source
 class Solution {  
 public:  
      int maxProfit(vector<int>& prices) {  
           int ans = 0;  
           for (int i = 1; i < prices.size(); i++) {  
                if (prices[i - 1] < prices[i]) {  
                     ans += (prices[i]- prices[i - 1]);  
                }  
           }  
           return ans;  
      }  
 };  

POJ.1338 Ugly Numbers

1.Problem
http://poj.org/problem?id=1338

2.Idea
Using 3 variables

3.Source
 ll ans[1502];  
 int main()  
 {  
      ans[1] = 1;  
      int u2 = 1, u3 = 1, u5 = 1;  
      for (int i = 2; i <= 1500; i++) {  
           int value2 = ans[u2] * 2;  
           int value3 = ans[u3] * 3;  
           int value5 = ans[u5] * 5;  
           ans[i] = min(min(value2, value3), value5);  
           if (ans[i] == value2) u2++;  
           if (ans[i] == value3) u3++;  
           if (ans[i] == value5) u5++;  
      }  
      int n;  
      while ((cin >> n), n)  
      {  
           cout << ans[n] << endl;  
      }  
      return 0;  
 }  

POJ.3006 Dirichlet's Theorem on Arithmetic Progressions

1.Problem
http://poj.org/problem?id=3006

2.Idea
Sieve of Eratosthenes

3.Source
 bool isPrime[1000006];  
 vector<int> Primes;  
 int a, d, n;  
 //Sieve of Eratosthenes  
 void prep()  
 {  
      for (int i = 2; i < 1000006; i++) {  
           if (isPrime[i]==0) {  
                Primes.push_back(i);  
                for (int j = i * 2; j < 1000006; j += i) {  
                     isPrime[j] = 1;  
                }  
           }  
      }  
 }  
 int main()  
 {  
      prep();  
      while (scanf("%d%d%d", &a, &d, &n) > 0) {  
           if (a + d + n == 0) break;  
           int cnt = 0;  
           for (int i = 0; i < Primes.size(); i++) {  
                if (Primes[i] >= a && (Primes[i] - a) % d == 0) {  
                     cnt++;  
                     if (cnt == n) {  
                          cout << Primes[i] << endl;  
                          break;  
                     }  
                }  
           }  
      }  
      return 0;  
 }  

Wednesday, April 1, 2020

POJ.2739 Sum of Consecutive Prime Numbers

1.Problem
http://poj.org/problem?id=2739

2.Idea
Enumerating primes

3.Source
 const int maxp = 2000;  
 int n = 10000;  
 int prime[maxp], total = 0;  
 bool isPrime(int k)  
 {  
      for (int i = 0; i < total; i++) {  
           if (k % prime[i] == 0) return false;  
      }  
      return true;  
 }  
 int main()  
 {  
      for (int i = 2; i <= n; i++) {  
           if (isPrime(i)) prime[total++] = i;  
      }  
      prime[total] = n + 1;  
      int m;  
      cin >> m;  
      while (m) {  
           int ans = 0;  
           for (int i = 0; m >= prime[i]; i++) {  
                int cnt = 0;  
                for (int j = i; j < total && cnt < m; j++) {  
                     cnt += prime[j];  
                }  
                if (cnt == m) ans++;  
           }  
           cout << ans << endl;  
           cin >> m;  
      }  
      return 0;  
 }