Codeforces Round #806 (Div. 4)

目录

官方题解

A. YES or YES?

B. ICPC Balloons

C. Cypher

D. Double Strings

E. Mirror Grid

F. Yet Another Problem About Pairs Satisfying an Inequality

G. Good Key, Bad Key


官方题解

点击跳转官方题解

A. YES or YES?

A. YES or YES?

思路:略

代码如下

#include <bits/stdc++.h>

#define fast ios::sync_with_stdio(false), cin.tie(nullptr); cout.tie(nullptr)

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const int N = 2e5 + 10;
const int mod = 998244353;

int T;

void solve()
{
    // 借鉴一下 jiaols 的代码,
    string s;
    cin >> s;
 
    if (toupper(s[0]) != 'Y') {
        cout << "NO\n";
        return;
    }
    if (toupper(s[1]) != 'E') {
        cout << "NO\n";
        return;
    }
    if (toupper(s[2]) != 'S') {
        cout << "NO\n";
        return;
    }
    cout << "YES\n";
    return;
}

int main()
{
    //fast; cin >> T;
    scanf("%d", &T);
    while(T -- )
        solve();
        
    return 0;
}

B. ICPC Balloons

B. ICPC Balloons

思路:略

代码如下

#include <bits/stdc++.h>

#define fast ios::sync_with_stdio(false), cin.tie(nullptr); cout.tie(nullptr)

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const int N = 2e5 + 10;
const int mod = 998244353;

int T;

void solve()
{
    int n;
    cin >> n;
    string s;
    cin >> s;
    map<char, int> mp;
    bool st = true;
    for(int i = 0; i < s.size(); i ++ )
        if(!mp[s[i]]) mp[s[i]] += 2;
        else mp[s[i]] += 1;
    
    int res= 0;
    for(auto it : mp)
        res += it.second;
    
    printf("%d\n", res);
    
    return;
}

int main()
{
    //fast; cin >> T;
    scanf("%d", &T);
    while(T -- )
        solve();
        
    return 0;
}

C. Cypher

C. Cypher

思路:枚举即可

代码如下:

#include <bits/stdc++.h>

#define fast ios::sync_with_stdio(false), cin.tie(nullptr); cout.tie(nullptr)

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const int N = 2e5 + 10;
const int mod = 998244353;

int T;

void solve()
{
	int n;
	cin >> n;
	int a[N];
	for(int i = 1; i <= n; i ++ )
			scanf("%d", &a[i]);

	for(int i = 1; i <= n; i ++ )
	{
		int t;
		string s;
		cin >> t >> s;
		for(auto c : s)
		{
			if(c == 'D') a[i] ++;
			else a[i] --;
		}
		a[i] %= 10;
		if(a[i] < 0) a[i] += 10;
		cout << a[i] << " ";
	}
	cout << endl;

    return;
}

int main()
{
    //fast; cin >> T;
    scanf("%d", &T);
    while(T -- )
        solve();
        
    return 0;
}

D. Double Strings

D. Double Strings

思路:双重枚举不可O(n^2) TLE,由题目条件可知,字符串长度最大为8,可以根据字符串长度枚举分割的位置,判断分隔开的两部分是否都存在,都存在则该字符串成立,反之不成立

s.substr(0, j) 为 s[0~j - 1] ,s.substr(j) 为 s[j ~ n]

注意:别乱使用字符串数组,声明即初始化,O(N) 的时间复杂度,,,(TLE好几次,,)

代码如下

#include <bits/stdc++.h>

#define fast ios::sync_with_stdio(false), cin.tie(nullptr); cout.tie(nullptr)

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const int N = 1e5 + 10;
const int mod = 998244353;

int T;

void solve()
{
    int n;
    cin >> n;
    
    string s[n + 2];
    
    map<string, int> mp;
    for(int i = 0; i < n; i ++ )
        cin >> s[i], mp[s[i]] = 1;
    
    for(int i = 0; i < n; i ++ )
    {
        int t = 0;
        for(int j = 1; j < s[i].size(); j ++ )
        {
            string a = s[i].substr(0, j);
            string b = s[i].substr(j);
            //cout << a << " " << b  << endl;
            if( mp[a] && mp[b] )
            {
                t = 1;
                cout << '1';
                break;
            }
        }
        if(t == 0)
            cout << '0';
    }
    
    cout << endl;
    
    //printf("%d\n", res);
    
    return;
}

int main()
{
    fast; cin >> T;
    //scanf("%d", &T);
    while(T -- )
        solve();
        
    return 0;
}

E. Mirror Grid

E. Mirror Grid

思路:判断中心对称的四个位置中,min(1的个数,0的个数),res += min;

具体旋转后的坐标可以参考如下:

证明:中心位置坐标为 ( (n+1)/2 , (n+1)/2 ) 

 代码如下

#include <bits/stdc++.h>

#define fast ios::sync_with_stdio(false), cin.tie(nullptr); cout.tie(nullptr)

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const int N = 110;
const int mod = 998244353;

int T;

void solve()
{
    int n;
    scanf("%d", &n);
    //cout << n << endl;
    char a[N][N];
    for(int i = 1; i <= n; i ++ )
        scanf("%s", a[i] + 1);

    int res = 0;
    for(int i = 1; i <= n; i ++ )
    {
        for(int j = 1; j <= n; j ++ )
            if(a[i][j] != '3')
            {
                int cnt = 0;
                cnt += a[i][j] + a[j][n - i + 1] + a[n - i + 1][n - j + 1] + a[n - j + 1][i] - 4 * '0';
                res += min(cnt, 4 - cnt);
                a[i][j] = a[j][n - i + 1] = a[n - i + 1][n - j + 1] = a[n - j + 1][i] = '3';
            }
    }

    cout << res << endl;

    return;
}

int main()
{
    //fast; cin >> T;
    scanf("%d", &T);
    while(T -- )
        solve();

    return 0;
}

F. Yet Another Problem About Pairs Satisfying an Inequality

F. Yet Another Problem About Pairs Satisfying an Inequality

思路

树状数组求和即可,

        a[i] 大于 n 的一定不满足 a[i] < j ,因为 n 最大 2e5,不加入树状数组中; 

        对于每个a[i] < i 求 大于 i 的 a[j] 的数量,即、sum(n) - sum( a[i] )

代码如下:

#include <bits/stdc++.h>

#define fast ios::sync_with_stdio(false), cin.tie(nullptr); cout.tie(nullptr)

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const int N = 2e5 + 10;
const int mod = 998244353;

int T;
int n;
int tr[N];

int lowbit(int x)
{
    return x & -x;
}

void add(int x, int c)
{
    for(int i = x; i <= n + 2; i += lowbit(i)) tr[i] += c;
}

LL sum(int x)
{
    LL res = 0;
    for(int i = x; i; i -= lowbit(i) ) res += tr[i];
    return res;
}

void solve()
{
    memset(tr, 0, sizeof tr);
    vector<int> v;
    int x;
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++ )
    {
        cin >> x;
        if(x < i)
        {
            v.push_back(i);
            if(x) add(x, 1);
        }
    }
    
    LL res = 0;
    for(int i = 0; i < (int)v.size(); i ++ )
        res += sum(n) - sum(v[i]);
    
    cout << res << endl;
    
    return;
}

int main()
{
    //fast; cin >> T;
    scanf("%d", &T);
    while(T -- )
        solve();
        
    return 0;
}

G. Good Key, Bad Key

G. Good Key, Bad Key

思路

线性DP,

 j 最多 31 ,32之后 获得的金币必定为 0 ,无意义。

初始化 f[i][j] 为1e-18,因为循环过程中可能产生挺大的负数,不能初始化为0

具体解释参考一下代码:

代码如下

#include <bits/stdc++.h>

#define fast ios::sync_with_stdio(false), cin.tie(nullptr); cout.tie(nullptr)

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const int N = 2e5 + 10;
const int mod = 998244353;

int T;
LL f[N][40]; // 第 i 个位置用了 j 个坏钥匙

void solve()
{
	int n, k;
	scanf("%d%d", &n, &k);
	
	int a[N];

	for(int i = 1; i <= n; i ++ )
		scanf("%d", &a[i]);

	for(int i = 1; i <= n; i ++ )
		for(int j = 0; j <= 31; j ++ )
			f[i][j] = -1e18;

	for(int i = 1; i <= n; i ++ )
	{
		f[i][0] = f[i - 1][0] - k + a[i]; // 没有坏钥匙的情况特判
		for(int j = 1; j <= 31; j ++ )
		{
			f[i][j] = max(f[i][j], f[i - 1][j - 1] + (a[i] >> j)); // 第 i 把是坏钥匙,则到第 i - 1 把时,用了 j - 1 把坏钥匙
			f[i][j] = max(f[i][j], f[i - 1][j] - k + (a[i] >> j)); // 第 i 把不是坏钥匙,则到第 i 把时,用了 j 把坏钥匙 
		}
		f[i][31] = max(f[i][31], f[i - 1][31]); // 已经用31把坏钥匙,之后的数都为0,特判
	}

	LL res = 0;
	for(int i = 0; i <= 31; i ++ ) // 判断每种情况的最大值
		res = max(res, f[n][i]);
	printf("%lld\n", res);

    return;
}

int main()
{
    //fast; cin >> T;
    scanf("%d", &T);
    while(T -- )
        solve();
        
    return 0;
}

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AC自动寄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值