Codeforces Round #606 (Div. 2)

Portal

A. Happy Birthday, Polycarp!

Sign.


Code

/*
 * Author:  heyuhhh
 * Created Time:  2019/12/14 19:07:57
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '\n'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
 
int n;
 
void run(){
    cin >> n;
    int x = n;
    int tot = 0;
    while(x) {
        ++tot; x /= 10;
    }   
    int ans = 0;
    for(int i = 1; i <= 9; i++) {
        ans += tot - 1;
        if(tot != 10) {
            int now = 0;
            for(int j = 1; j <= tot; j++) now = now * 10 + i;
            if(now <= n) ++ans;
        }
    }
    cout << ans << '\n';
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    int T; cin >> T;
    while(T--) run();
    return 0;
}

B. Make Them Odd

Analog with a descending set about this process can be.


Code

/*
 * Author:  heyuhhh
 * Created Time:  2019/12/14 19:13:49
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '\n'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
 
set <int> S;
 
void run(){
    int n; cin >> n;
    for(int i = 1; i <= n; i++) {
        int x; cin >> x;
        if((x & 1) == 0) S.insert(x);
    }
    int ans = 0;
    while(!S.empty()) {
        auto it = S.end(); --it;
        int now = *it; 
        S.erase(it);
        now >>= 1;
        if((now & 1) == 0) S.insert(now);
        ++ans;
    }
    cout << ans << '\n';
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    int T; cin >> T;
    while(T--) run();
    return 0;
}

C. As Simple as One and Two

Meaning of the questions:
given a string \ (S \) , and now you want to delete a character minimum, so that the string does not contain \ (One, TWO \) .

Ideas:
immediate idea is to find \ (one, two \) is deleted, but here there may be a problem: for example, \ (twoone, tttwo \) This, clearly superior to delete method.
For word repetition of the situation, obviously we delete a \ (w \) and a \ (n \) best (because only may be repeated on both sides).
In the case of connecting the two words, we removed a \ (o \) is optimal.
So with different situations can be.


Code

/*
 * Author:  heyuhhh
 * Created Time:  2019/12/14 19:26:17
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '\n'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 2e5 + 5;
 
char s[N];
int del[N];
 
bool chk1(int p) {
    return s[p] == 'o' && s[p + 1] == 'n' && s[p + 2] == 'e';  
}
 
bool chk2(int p) {
    return s[p] == 't' && s[p + 1] == 'w' && s[p + 2] == 'o';   
}
 
void run(){
    cin >> (s + 1);
    int n = strlen(s + 1);
    for(int i = 1; i <= n; i++) del[i] = 0;
    for(int i = 1; i <= n - 2; i++) {
        if(chk2(i)) {
            if(i + 3 <= n && s[i + 3] == 'o') del[i + 1] = 1;
            else del[i + 2] = 1;
        }   
        if(chk1(i)) {
            if(i - 1 >= 1 && s[i - 1] == 'o') del[i + 1] = 1;
            else del[i] = 1;   
        }
    }
    int ans = 0;
    for(int i = 1; i <= n; i++) ans += del[i];
    cout << ans << '\n';
    for(int i = 1; i <= n; i++) if(del[i]) cout << i << ' ';
    cout << '\n';
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    int T; cin >> T;
    while(T--) run();
    return 0;
}

D. Let's Play the Words?

Meaning of the questions:
given a number of different from each other \ (01 \) string, flip least ask how many times met:

  • All string different from each other
  • The presence of one embodiment, can be joined together so that the string

Here it does not require splicing to form a ring, but linear spliced ​​together, the splice can be the same as long as the head and tail, and we can arrange in any order.

Thinking:
said after \ (XY \) string refers to a head for the \ (X \) , for the tail \ (Y \) string.

  • First, notice that we flip \ (00,11 \) string useless, we can focus on \ (01, 10 \) string.
  • Assuming that the number of both are \ (A, B \) , might \ (A <B \) , without considering the situation reversed, apparently greedy spliced, i.e. \ (10-01- \ cdots-10 \ ) .
  • Obviously, we only need to \ (\ lfloor \ frac {ba } {2} \ rfloor \) a \ (10 \) strings can be inverted.
  • Finally, select Flip's strategy is to be able to flip flip, we use a \ (map \) to determine whether to overturn.
  • Another \ (a \ geq b \) similar situations.

In short, greedy + \ (the Map \) .


Code

/*
 * Author:  heyuhhh
 * Created Time:  2019/12/14 19:48:43
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '\n'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 2e5 + 5;
 
int n;
string s[N];
map <string, int> mp;
int cnt[2][2];
bool chk[N];
 
string rev(string &S) {
    reverse(S.begin(), S.end());
    return S;
}
 
void run(){
    cin >> n;
    mp.clear();
    for(int i = 1; i <= n; i++) chk[i] = 0;
    cnt[0][1] = cnt[1][0] = 0;
    for(int i = 1; i <= n; i++) {
        cin >> s[i];
        int len = s[i].length();
        if(len > 1) {
            if(s[i][0] != s[i][len - 1]) mp[s[i]] = i;
            if(s[i][0] == '0' && s[i][len - 1] == '1') ++cnt[0][1];
            else if(s[i][0] == '1' && s[i][len - 1] == '0')++cnt[1][0];
        }    
    }
    if(cnt[0][1] == 0 && cnt[1][0] == 0) {
        int cnt1 = 0, cnt2 = 0;
        for(int i = 1; i <= n; i++) {
            int len = s[i].length();
            if(s[i][0] == '0' && s[i][len - 1] == '0') ++cnt1;
            else ++cnt2;   
        }
        if(cnt1 && cnt2) cout << -1 << '\n';
        else cout << 0 << '\n' << '\n';
        return;   
    }
    int d = abs(cnt[0][1] - cnt[1][0]);
    int need = d / 2, ans;
    if(cnt[0][1] > cnt[1][0]) {
        for(int i = 1; i <= n && need; i++) {
            int len = s[i].length();
            if(len > 1 && s[i][0] == '0' && s[i][len - 1] == '1') {
                rev(s[i]);
                if(mp.find(s[i]) == mp.end()) {
                    --need; chk[i] = 1;  
                } 
                rev(s[i]);
            }   
        }
    } else {
        for(int i = 1; i <= n && need; i++) {
            int len = s[i].length();
            if(len > 1 && s[i][0] == '1' && s[i][len - 1] == '0') {
                rev(s[i]);
                if(mp.find(s[i]) == mp.end()) {
                    --need; chk[i] = 1;  
                } 
                rev(s[i]);
            }   
        }  
    }
    if(need == 0) ans = d / 2;   
    else {
        cout << -1 << '\n';
        return;   
    }
    cout << ans << '\n';
    for(int i = 1; i <= n; i++) if(chk[i]) cout << i << ' ';
    cout << '\n';
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    int T; cin >> T;
    while(T--) run();
    return 0;
}

E. Two Fairs

The meaning of problems:
given \ (n-\) points, \ (m \) without communication to the edges of FIG.
Give two given points \ (A, B \) , asks \ ((x, y) \ ) logarithm. Wherein \ ((x, y) \ ) is a legitimate need to meet \ (X \) to \ (Y \) path must be \ (a, b \) these two points.
\ ((x, y), (y, x) \) is the same situation.

Ideas:
beginning to think that undirected graph shrink point to a tree, and then engage in the trees. The method is feasible, but too complex.
The original problem is two paths must be \ (A, b \) , that is, from (a \) \ point of view, must be \ (b \) to get to a certain point; from \ (b \) departure. It must be \ (a \) to reach a certain point.
So we ran twice \ (the DFS \) , respectively, from the \ (a, b \) set out to find the \ (a, b \) do not proceed through all the other points that can be reached, then the remaining point is the need to go through the point of arrival.
Multiplied by the number of both is the answer.
The essence of the idea is to "shorten the path", originally ran \ (n \) times the problem only run twice.
code show as below:


Code

/*
 * Author:  heyuhhh
 * Created Time:  2019/12/14 20:12:26
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '\n'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 2e5 + 5, M = 5e5 + 5;
 
int n, m, a, b;
struct Edge {
    int v, next;
}e[M << 1];
int head[N], tot;
void adde(int u, int v) {
    e[tot].v = v; e[tot].next = head[u]; head[u] = tot++;
}
int cnt;
int col[N];
void init() {
    for(int i = 1; i <= n; i++) head[i] = -1; tot = 0;   
}
void dfs(int u, int fa, int x) {
    col[u] = 1;
    if(u == x) return;   
    for(int i = head[u]; i != -1; i = e[i].next) {
        int v = e[i].v;
        if(!col[v]) dfs(v, u, x);
    }
}
 
void run(){
    cin >> n >> m >> a >> b;
    init();
    for(int i = 1; i <= m; i++) {
        int u, v; cin >> u >> v;
        adde(u, v); adde(v, u);
    }
    dfs(a, 0, b);
    int cnt1 = 0, cnt2 = 0;
    for(int i = 1; i <= n; i++) {
        cnt1 += 1 - col[i];
        col[i] = 0;   
    }
    dfs(b, 0, a);
    for(int i = 1; i <= n; i++) {
        cnt2 += 1 - col[i];   
        col[i] = 0;
    }
    ll ans = 1ll * cnt1 * cnt2;
    cout << ans << '\n';
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    int T; cin >> T;
    while(T--) run();
    return 0;
}

Guess you like

Origin www.cnblogs.com/heyuhhh/p/12043602.html