《看了受制了》第四十六天,11道题,合计290道题

发布时间 2023-10-22 21:39:06作者: wxzcch

2023年10月22日

牛客小白月赛 数位dp?

题目理解

两个要求,要最后的值是偶数,所以不是偶数就÷10,答案加一即可。

代码实现

int main()
{
    int n;
    cin >> n;
    int res = 0;
    while(n % 2 != 0)
        n /= 10, res ++;
    cout << res;
}

牛客小白月赛 灵异背包?

题目理解

答案和是偶数,就是答案,不是就减去最小的奇数

代码实现

#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;

typedef long long ll;
int main()
{
    ll res = 0;
    vector<ll> vec;
    int n;
    cin >> n;
    ll k;
    for(int i = 1; i <= n; i++)
    {
        cin >> k;
        res += k;
        if(k % 2 == 1) vec.push_back(k);
    }
    sort(vec.begin(), vec.end());
    
    if(res % 2) cout << res - vec[0];
    else cout << res;
}

牛客小白月赛 mex和gcd的乘积

题目理解

如果mex不是1,那么gcd必是1
如果mex是1,那么gcd就会大
所以答案,要么就是整个序列的mex,要么就是0旁边的最大值。
如果整个序列都是0,那么值只能是0

代码实现

#include "bits/stdc++.h"

using namespace std;
using i64 = long long;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;
    vector<int> a(n);
    vector<int> vis(n + 1);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        vis[a[i]] = 1;
    }

    int ans = 0;
    for (int i = 0; i < n; i++) {
        if (a[i] == 0) {
            if (i + 1 < n) {
                ans = max(ans, a[i + 1]);
            }
            if (i - 1 >= 0) {
                ans = max(ans, a[i - 1]);
            }
        }
    }

    int mex = 0;
    while (vis[mex]) {
        mex++;        
    }

    if (mex > 1) {
        ans = max(ans, mex);
    }    
    cout << ans << '\n';

    return 0;
}

牛客小白月赛 2^20

题目理解

可以发现,子弹是无限的,所以并不会打光。
那么就是两个操作:

  • x = x * 2
  • x = x + 1
    那么就枚举操作即可,操作是不超过20的。

代码实现

typedef long long ll;
const int N = 1048576 + 10, M = 1048576;
int a[N];
int step[N];

bool check(int u)
{
    int q = 1;
    while(q < u) q *= 2;
    if(u == q) return false;
    return true;
}

int bfs(int u)
{

    if(u == 0) return 0;
    
    int ans=20;
    for(int i=0;i <= 20;i++){ //累加20次
        int temp = u;
        int cnt = 0;
        while(temp % 2 == 0) cnt++,temp/=2;  //统计01后面串有几个0
        ans = min(ans, i + 20 - cnt);  //20-cnt就是有左移的次数
        u++;
    }
    return ans;
}

int main()
{
    int T;
    cin >> T;
    while(T--)
    {
        int n;
        cin >> n;
        
        cout << bfs(n % M) << endl;
    }
    return 0;
}

Acwing周赛 A 蜗牛爬

题目理解

就如果大于5,就是n - 5 + 1
如果小于等于就是1

代码实现

int main()
{
    int n;
    cin >> n;
    if(n <= 5) cout << 1;
    else cout << n - 5 + 1;
    return 0;
}

Acwing周赛 B 替换字符

题目理解

枚举每一个位置的错误个数,用最小的那个即可。

代码实现

typedef pair<int, int> PII;
const int N = 1010;
vector<PII> q;
int main()
{
    int n, m;
    cin >> n >> m;
    string s, t;
    cin >> s >> t;
    for(int i = 0; i <= m - n; i++)
    {
        int cnt = 0;
        for(int k = 0, j = i; k < n; k++, j++)
            if(s[k] != t[j])
                cnt++;

        q.push_back({cnt, i});
    }       
    sort(q.begin(), q.end());


    int flag = q[0].y;
    int res = q[0].x;
    cout << res << endl;
    for(int k = 0, j = flag; k < n; k++, j++)
        if(s[k] != t[j])
            cout << k + 1 << " ";
    return 0;
}

Acwing周赛 扩展字符串

题目理解

预处理出来能求出的长度。如果超出了就返回'.'
如果:

  • 是0,就返回s[k - 1]
  • 是a的区间就返回a[k - 1]
  • 是b的区间就返回b[k - 1]
  • 是c的区间就返回c[k - 1]
  • 是s的话就划分成子问题,继续递归。

代码实现

#include<bits/stdc++.h>
using namespace std;
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;

const int N = 1e5 + 10, Mod = 1e9 + 7;
const ll INF = 2e18;

ll len[N + 5];
string s = "DKER EPH VOS GOLNJ ER RKH HNG OI RKH UOPMGB CPH VOS FSQVB DLMM VOS QETH SQB";
string a = "DKER EPH VOS GOLNJ UKLMH QHNGLNJ A";
string b = "AB CPH VOS FSQVB DLMM VOS QHNG A";
string c = "AB";

char dfs(ll n, ll k)
{
    if(k > len[n]) return '.';
    if(n == 0) return s[k - 1];

    if(k <= a.size()) return a[k - 1];

    k -= a.size();
    if(k <= len[n - 1]) return dfs(n - 1, k);

    k -= len[n - 1];
    if(k <= b.size()) return b[k - 1];

    k -= b.size();

    if(k <= len[n - 1]) return dfs(n - 1, k);
    k -= len[n - 1];

    return c[k - 1];
}

void solve()
{

    int q;
    cin >> q;
    while(q -- )
    {
        ll n, k;
        cin >> n >> k;
        cout << dfs(n, k);
    }

    return;
}

int main()
{
    len[0] = s.size();
    for(int i = 1; i <= N; i++)
    {
        len[i] = len[i - 1] * 2 + a.size() + b.size() + c.size();
        len[i] = min(len[i], INF);
    }
    int T = 1;
    while(T--) solve();
    return 0;
}

Atcoder325 A 签到题

题目理解

直接输出姓和san即可

代码实现

void solve()
{

	string s, t;
	cin >> s >> t;

	cout << s << " " << "san";

	return;
}

Atcoder325 B World Meeting

题目理解

枚举24个小时,看那个时候是否符合区域。如果符合就加上去

代码实现

const int N = 1010;
int w[N], c[N];
int n, res;

void solve()
{

	cin >> n;

	for(int i = 1; i <= n; i++)
		cin >> w[i] >> c[i];

	for(int i = 0; i <= 24; i++)
	{
		int cnt = 0;

		for(int j = 1; j <= n; j++)
		{

			int k = c[j] + i;
			if(k >= 24) k -= 24;

			if(k >= 9 && k < 18) cnt += w[j];
		}
		
		res = max(res, cnt);
	}

	cout << res;
	return;
}

Div.3 Round905 A - Morning

题目理解

我需要看这个数和需要的数是否一样,一样就res++
不一样就移过去再res++

代码实现

void solve()
{
	string s;
	cin >> s;

	int res = 0;

	char c = '1';

	for(int i = 0; i < 4; i++)
	{
		if(s[i] == c || (s[i] == '0' && c == '9' + 1))
		{
			res ++;
		}else{
			int t = 0;
			if(s[i] == '0')
			{
				t = abs(('9' + 1) - c);
				c = '9' + 1;
			}else{
				t = abs(s[i] - c);
				c = s[i];
			}

			res+=t + 1;
		}
	}

	cout << res << endl;

	return;
}

Div.3 Round905 B

题目理解

如果k是0,就看原本是不是回问
如果差是1,就一定是
如果差是奇数,就要(t - 1) / 2对
如果差是偶数,就要t / 2对

代码实现

#include <iostream>
#include <cstring>
using namespace std;

const int N = 26;
int cnt[N];

bool check(string s)
{
    memset(cnt, 0, sizeof cnt);
    for(char ch : s)
        cnt[ch - 'a']++;
    
    int oddCnt = 0;
    for(int i = 0; i < N; i++)
        if(cnt[i] % 2 == 1)
            oddCnt++;
    
    return oddCnt <= 1;
}

bool isPossible(int n, int k, string s)
{
    int t = n - k;

    if (t == 0) {
        return check(s);
    } else if (t == 1) {
        return true;
    } else {
        memset(cnt, 0, sizeof cnt);
        for(char ch : s)
            cnt[ch - 'a']++;

        int pairs = 0;
        for(int i = 0; i < N; i++)
            pairs += cnt[i] / 2;

        if(t % 2 == 0) {
            return pairs >= t / 2;
        } else {
            if(pairs > (t - 1) / 2)
                return true;
            else if(pairs == (t - 1) / 2) {
                for(int i = 0; i < N; i++)
                    if(cnt[i] % 2 == 1)
                        return true;
                return false;
            } else {
                return false;
            }
        }
    }
}

int main()
{
    int T;
    cin >> T;
    while (T--) {
        int n, k;
        cin >> n >> k;
        string s;
        cin >> s;
        if (isPossible(n, k, s))
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }

    return 0;
}