Codeforces Round #606 (Div. 2, based on Technocup 2020 Elimination Round 4) 题解

Happy Birthday, Polycarp!

\[ Time Limit: 1 s\quad Memory Limit: 256 MB \]
暴力枚举所有数字全为 \(i、i\in[1,9]\),然后暴力判断有多个全为 \(i\) 的数在 \(n\) 以内即可。


view

#include <unordered_map>
#include <set>
#include <list>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <cfloat>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define  lowbit(x)  x & (-x)
#define  mes(a, b)  memset(a, b, sizeof a)
#define  fi         first
#define  se         second
#define  pb         push_back
#define  pii        pair<int, int>
#define  INOPEN     freopen("in.txt", "r", stdin)
#define  OUTOPEN    freopen("out.txt", "w", stdout)

typedef unsigned long long int ull;
typedef long long int ll;
const int    maxn = 1e5 + 10;
const int    maxm = 1e5 + 10;
const ll     mod  = 1e9 + 7;
const ll     INF  = 1e18 + 100;
const int    inf  = 0x3f3f3f3f;
const double pi   = acos(-1.0);
const double eps  = 1e-8;
using namespace std;

ll n, m;
int cas, tol, T;

int main() {
    scanf("%d", &T);
    while(T--) {
        ll ans = 0;
        scanf("%lld", &n);
        for(int i=1; i<=9; i++) {
            ll tmp = i;
            while(tmp <= n) {
                ans++;
                tmp = tmp*10+i;
            }
        }
        printf("%lld\n", ans);
    }
    return 0;
}

Make Them Odd

\[ Time Limit: 3 s\quad Memory Limit: 256 MB \]
把数一直除 \(2\),记录除了多少次。

那么对于剩余的数相同的数,只要记录变成他需要被除的最大次数就即可。

最后的答案就是变成这些剩余数的所需次数的累和。


view

#include <map>
#include <set>
#include <list>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <cfloat>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define  lowbit(x)  x & (-x)
#define  mes(a, b)  memset(a, b, sizeof a)
#define  fi         first
#define  se         second
#define  pb         push_back
#define  pii        pair<int, int>
#define  INOPEN     freopen("in.txt", "r", stdin)
#define  OUTOPEN    freopen("out.txt", "w", stdout)

typedef unsigned long long int ull;
typedef long long int ll;
const int    maxn = 1e5 + 10;
const int    maxm = 1e5 + 10;
const ll     mod  = 1e9 + 7;
const ll     INF  = 1e18 + 100;
const int    inf  = 0x3f3f3f3f;
const double pi   = acos(-1.0);
const double eps  = 1e-8;
using namespace std;

int n, m;
int cas, tol, T;

map<int, int> mp;

int main() {
    scanf("%d", &T);
    while(T--) {
        scanf("%d", &n);
        mp.clear();
        ll ans = 0;
        for(int i=1, x; i<=n; i++) {
            scanf("%d", &x);
            int res = 0;
            while(x%2 == 0) {
                res++;
                x /= 2;
            }
            if(mp.count(x)) mp[x] = max(mp[x], res);
            else    mp[x] = res;
        }
        for(auto v : mp)    ans += v.se;
        printf("%lld\n", ans);
    }
    return 0;
}

As Simple as One and Two

\[ Time Limit: 3 s\quad Memory Limit: 256 MB \]
首先考虑 \(twone\),这里因为的 \(o\)\(one\)\(two\) 都用到了,所以直接删除它就可以了。

在考虑其他情况,对于 \(one\) 可能存在 \(one、oneeee、oooone、oooneeee\),那么我们可以发现,删掉 \(o\) 或者删掉 \(e\) 都不是很好的选择,但是 \(n\) 确实不能重复出现的,所以只要删掉 \(n\) 就可以了。对于 \(two\) 也是一样的道理,删掉 \(w\) 是最好的。


view

#include <map>
#include <set>
#include <list>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <cfloat>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define  lowbit(x)  x & (-x)
#define  mes(a, b)  memset(a, b, sizeof a)
#define  fi         first
#define  se         second
#define  pb         push_back
#define  pii        pair<int, int>
#define  INOPEN     freopen("in.txt", "r", stdin)
#define  OUTOPEN    freopen("out.txt", "w", stdout)

typedef unsigned long long int ull;
typedef long long int ll;
const int    maxn = 2e5 + 10;
const int    maxm = 1e5 + 10;
const ll     mod  = 1e9 + 7;
const ll     INF  = 1e18 + 100;
const int    inf  = 0x3f3f3f3f;
const double pi   = acos(-1.0);
const double eps  = 1e-8;
using namespace std;

int n, m;
int cas, tol, T;

char s[maxn];

int main() {
    scanf("%d", &T);
    while(T--) {
        vector<int> ans;
        scanf("%s", s+1);
        int len = strlen(s+1);
        for(int i=1; i<=len; i++) {
            if(i+2<=len && s[i]=='t' && s[i+1]=='w' && s[i+2]=='o') {
                if(i+4<=len && s[i+3]=='n' && s[i+4]=='e') {
                    ans.pb(i+2);
                    i = i+4;
                } else {
                    ans.pb(i+1);
                    i = i+2;
                }
            }
            if(i+2<=len && s[i]=='o' && s[i+1]=='n' && s[i+2]=='e') {
                ans.pb(i+1);
                i = i+2;
            }
        }
        printf("%d\n", ans.size());
        for(auto v : ans)   printf("%d ", v);
        printf("\n");
    }
    return 0;
}

Let's Play the Words?

\[ Time Limit: 3 s\quad Memory Limit: 256 MB \]
把字符串分成四类,分别是 \(0..0、1...1、0...1、1...0\)

首先可以发现,如果存在一个第 \(3/4\) 类的字符串,第 \(1/2\) 类的字符串都一定能够拼接起来,完全可以忽略掉。如果不存在第 \(3/4\) 类的字符串,那么 \(1/2\) 类的字符串只能独自出现,否则一定拼接不起来。

接下来考虑存在 \(3/4\) 类的字符串,第 \(3\) 类的字符串有 \(n\) 个,第 \(4\) 类的字符串有 \(m\) 个。
假设 \(n>m\),那么我们只要暴力翻转第 \(3\) 类的字符串变成第 \(4\) 类的字符串,使得 \(abs(n-m)<=1\),就一定可以拼接起来,对于 \(m>n\) 的情况也是类似,只要翻转第 \(4\) 类的字符串变成第 \(3\) 类的就可以。

为什么这么做可以呢?因为题目保证的一开始给出的字符串都是 \(different\) 的,那么我把第 \(3\) 类的字符串翻转过去,一定不会对其他第 \(3\) 类字符串是否需要翻转造成影响,那么我只要每次贪心翻转就够了。


view

#include <unordered_map>
#include <set>
#include <list>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <cfloat>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define  lowbit(x)  x & (-x)
#define  mes(a, b)  memset(a, b, sizeof a)
#define  fi         first
#define  se         second
#define  pb         push_back
#define  pii        pair<int, int>
#define  INOPEN     freopen("in.txt", "r", stdin)
#define  OUTOPEN    freopen("out.txt", "w", stdout)
 
typedef unsigned long long int ull;
typedef long long int ll;
const int    maxn = 1e5 + 10;
const int    maxm = 1e5 + 10;
const ll     mod  = 1e9 + 7;
const ll     INF  = 1e18 + 100;
const int    inf  = 0x3f3f3f3f;
const double pi   = acos(-1.0);
const double eps  = 1e-8;
using namespace std;
 
int n, m;
int cas, tol, T;
 
unordered_map<string, bool> mp;
vector<pair<string, int> > vv[4];
 
int main() {
    scanf("%d", &T);
    while(T--) {
        mp.clear();
        for(int i=0; i<4; i++)  vv[i].clear();
        scanf("%d", &n);
        string s;
        for(int i=1; i<=n; i++) {
            cin >> s;
            if(s[0]=='0' && s[s.length()-1]=='0')   vv[0].pb({s, i});
            if(s[0]=='1' && s[s.length()-1]=='1')   vv[1].pb({s, i});
            if(s[0]=='0' && s[s.length()-1]=='1')   vv[2].pb({s, i});
            if(s[0]=='1' && s[s.length()-1]=='0')   vv[3].pb({s, i});
        }
        if(vv[0].size() == n || vv[1].size() == n) {
            printf("0\n\n");
            continue;
        }
        if(vv[0].size() && vv[1].size() && !vv[2].size() && !vv[3].size()) {
            printf("-1\n");
            continue;
        }
        int id = 2;
        if(vv[3].size() > vv[2].size()) id = 3;
        n = vv[id].size(), m = vv[id^1].size();
        vector<int> ans;
        for(auto it : vv[id^1]) mp[it.fi] = true;
        for(auto it : vv[id]) {
            if(abs(n-m) <= 1)   break;
            string ss = it.fi;
            reverse(ss.begin(), ss.end());
            if(mp.count(ss))    continue;
            ans.push_back(it.se);
            n--, m++;
        }
            int sz = ans.size();
            printf("%d\n", sz);
            if(sz==0)   printf("\n");
            for(int i=0; i<sz; i++)
                printf("%d%c", ans[i], i==sz-1 ? '\n':' ');
        
    }
    return 0;
}

Two Fairs

\[ Time Limit: 3 s\quad Memory Limit: 256 MB \]
对于给出的开始和终止位置 \(s、t\),我需要找到的是从 \(s\) 出发不经过 \(t\) 可以到达的节点数和从 \(t\) 出发不经过 \(s\) 可以到达的节点数。

对于找从 \(s\) 出发不经过 \(t\) 的节点,可以先 \(dfs\) 一边把从 \(t\) 出发可以到达的节点数标记起来,终止条件为遇到 \(s\) 节点或者无路可走。然后再从 \(s\) 出发看哪些节点是没有被标记过的。这样找出来的节点就一定是满足条件的,第二种同理。

最后的答案就是这两种节点数的乘积。


view

#include <map>
#include <set>
#include <list>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <cfloat>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define  lowbit(x)  x & (-x)
#define  mes(a, b)  memset(a, b, sizeof a)
#define  fi         first
#define  se         second
#define  pb         push_back
#define  pii        pair<int, int>
#define  INOPEN     freopen("in.txt", "r", stdin)
#define  OUTOPEN    freopen("out.txt", "w", stdout)

typedef unsigned long long int ull;
typedef long long int ll;
const int    maxn = 2e5 + 10;
const int    maxm = 1e5 + 10;
const ll     mod  = 1e9 + 7;
const ll     INF  = 1e18 + 100;
const int    inf  = 0x3f3f3f3f;
const double pi   = acos(-1.0);
const double eps  = 1e-8;
using namespace std;

int n, m;
int cas, tol, T;

int s, t;
vector<int> g[maxn];
bool vis[maxn];

void dfs1(int u, int res) {
    if(vis[u])  return ;
    if(u == res)    return ;
    vis[u] = 1;
    for(auto v : g[u])  dfs1(v, res);
}

ll dfs(int u) {
    if(vis[u])  return 0;
    vis[u] = 1;
    ll ans = 1;
    for(auto v : g[u])  
        ans += dfs(v);
    return ans;
}

int main() {
    scanf("%d", &T);
    while(T--) {
        scanf("%d%d%d%d", &n, &m, &s, &t);
        for(int i=1; i<=n; i++) g[i].clear();
        for(int i=1, u, v; i<=m; i++) {
            scanf("%d%d", &u, &v);
            g[u].pb(v), g[v].pb(u);
        }
        ll ans1 = 0, ans2 = 0;
        for(int i=1; i<=n; i++) vis[i] = 0;
        dfs1(t, s);
//      for(int i=1; i<=n; i++) printf("%d%c", vis[i], i==n?'\n':' ');
        ans1 = dfs(s)-1;
        for(int i=1; i<=n; i++) vis[i] = 0;
        dfs1(s, t);
//      for(int i=1; i<=n; i++) printf("%d%c", vis[i], i==n?'\n':' ');
        ans2 = dfs(t)-1;
        printf("%lld\n", ans1*ans2);
    }
    return 0;
}

Beautiful Rectangle

\[ Time Limit: 1 s\quad Memory Limit: 256 MB \]
待填坑。

猜你喜欢

转载自www.cnblogs.com/Jiaaaaaaaqi/p/12046792.html