Loading

Codeforces Round #806 (Div. 4) A - G

传送门

A. YES or YES?

统一一下大小写

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;

int main()
{
    int t;
    cin >> t;
    while(t--)
    {
        string s;
        cin >> s;
        for(int i=0; i<s.length(); i++)
        {
            if(s[i] >= 'a' && s[i] <= 'z')
                s[i] = s[i] - 'a' + 'A';
        }
        if(s == "YES") cout << "YES\n";
        else cout << "NO\n";
    }
    return 0;
}

B. ICPC Balloons

找下有多少种不同的字母,再加上字符串长

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
int vis[maxn];

int main()
{
    int t;
    cin >> t;
    while(t--)
    {
        int n;
        string s;
        cin >> n >> s;
        for(int i='A'; i<='Z'; i++) vis[i] = 0;
        int ans = 0;
        for(int i=0; i<s.length(); i++)
        {
            if(vis[s[i]] == 0) ans++;
            vis[s[i]] = 1;
        }
        ans += s.length();
        cout << ans << endl;
    }
    return 0;
}

C. Cypher

模拟

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
int num[maxn];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--)
    {
        int n;
        cin >> n;
        for(int i=0; i<n; i++) cin >> num[i];
        for(int i=0; i<n; i++)
        {
            int k;
            string s;
            cin >> k >> s;
            for(int j=0; j<k; j++)
            {
                if(s[j] == 'D')
                {
                    num[i]++;
                    if(num[i] == 10) num[i] = 0;
                }
                else
                {
                    num[i]--;
                    if(num[i] == -1) num[i] = 9;
                }
            }
        }
        for(int i=0; i<n; i++)
        {
            if(i) cout << " ";
            cout << num[i];
        }
        cout << '\n';
    }
    return 0;
}

D. Double Strings

长度为 8 的字符串,直接 map + 字符串分割

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
string s[maxn];
map<string, int>mp;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--)
    {
        mp.clear();
        int n;
        cin >> n;
        for(int i=0; i<n; i++)
        {
            cin >> s[i];
            mp[s[i]] = 1;
        }
        for(int i=0; i<n; i++)
        {
            string now = "";
            int f = 0;
            for(int j=1; f == 0 && j<s[i].length(); j++)
            {
                now += s[i][j-1];
                if(mp[now] && mp[string(s[i], j, s[i].length() - j)])
                    f = 1;
            }
            cout << f;
        }
        cout << '\n';
    }
    return 0;
}

E. Mirror Grid

旋转四下,相当于四个位置一组,然后判断一下化为 1 好,还是化为 0 好

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 110;
const ll inf = 1e17 + 10;
int vis[maxn][maxn];
string s[maxn];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--)
    {
        int n;
        cin >> n;
        for(int i=0; i<n; i++) for(int j=0; j<n; j++) vis[i][j] = 0;
        for(int i=0; i<n; i++) cin >> s[i];
        int ans = 0;
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
            {
                if(vis[i][j]) continue;
                int f = 0;
                f += s[i][j] - '0';
                vis[i][j] = 1;
                f += s[n-i-1][n-j-1] - '0';
                vis[n-i-1][n-j-1] = 1;
                f += s[j][n-i-1] - '0';
                vis[j][n-i-1] = 1;
                f += s[n-j-1][i] - '0';
                vis[n-j-1][i] = 1;
                ans += min(f, 4 - f);
            }
        }
        cout << ans << '\n';
    }
    return 0;
}

F. Yet Another Problem About Pairs Satisfying an Inequality

前缀和

找一下前 \(k\) 个符合 \(a_i < i\) 的数量,然后再枚举每一个 \(j\),每个位置上的贡献就为 pre[a_j-1]

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
ll sum[maxn];
int a[maxn];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--)
    {
        int n;
        cin >> n;
        for(int i=1; i<=n; i++)
        {
            cin >> a[i];
            if(i > a[i]) sum[i]++;
            sum[i] += sum[i-1];
        }
        ll ans = 0;
        for(int i=1; i<=n; i++)
            if(i > a[i] && a[i]) ans += sum[a[i] - 1];
        cout << ans << '\n';
        for(int i=0; i<=n; i++) sum[i] = 0;
    }
    return 0;
}

G. Good Key, Bad Key

dp 或 贪心

注意题目可负债!

因为箱子的价值不超过 \(10^9\),因此最多使用 \(32\) 次不好的钥匙之后,所有箱子的价值都会变成 \(0\)

因此有 \(dp[i][j]\) 表示在开完第 \(i\) 个箱子,用了 \(j\) 把坏钥匙之后的最大值

有转移方程:\(dp[i][j] = max(dp[i-1][j] - k + a[i][j], dp[i-1][j-1] + a[i-1][j-1])\),第一项表示用好钥匙转移,第二项表示用坏钥匙转移

如果你用了以上转移方程 wa4,则要看看下面这个

但是以上这种转移方式显然忽略了一种情况:\(j\) 的最后一层并不代表只使用 \(j\) 次,它表示使用了 \(j\) 及其 \(j\) 以上个坏钥匙

因此还应该增加一个针对于最后一层的转移方程:\(dp[i][32] = max(dp[i][32], dp[i-1][32])\)

或者答案直接选取 dp 数组里出现过的最大值,因为只要出现过,一直选坏钥匙都不会导致答案变差

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e16;
ll a[maxn][35];
ll dp[maxn][35];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--)
    {
        ll n, k;
        cin >> n >> k;
        for(int i=1; i<=n; i++) for(int j=0; j<=32; j++) dp[i][j] = -inf;
        for(int i=1; i<=n; i++)
        {
            cin >> a[i][0];
            for(int j=1; j<=32; j++)
                a[i][j] = a[i][j-1] >> 1;
        }
        dp[0][0] = 0;
        ll ans = 0;
        for(int i=1; i<=n; i++)
        {
            dp[i][0] = dp[i-1][0] - k + a[i][0];
            ans = max(ans, dp[i][0]);
            for(int j=1; j<=min(32, i); j++)
            {
                dp[i][j] = max({dp[i][j], dp[i-1][j] - k + a[i][j], dp[i-1][j-1] + a[i][j]});
            }
            dp[i][32] = max(dp[i][32], dp[i-1][32]);
        }
        for(int i=0; i<=32; i++) ans = max(ans, dp[n][i]);
        cout << ans << endl;
    }
    return 0;
}
posted @ 2022-07-13 20:19  dgsvygd  阅读(41)  评论(0编辑  收藏  举报