牛客小白月赛110


A. 智乃办赛

首先算出这个人在哪个字母里,然后对500取余就可以得到编号。

点击查看代码
void solve() {
    int n;
    std::cin >> n;
    char c = (n - 1) / 500 + 'A';
    n %= 500;
    if (n == 0) {
    	n = 500;
    }
    std::string s = std::to_string(n);
    while (s.size() < 3) {
    	s = "0" + s;
    }
    std::cout << c << s << "\n";
}

B. 智乃的Wordle

题意:比较两个长度为8的字符串,每一位如果相同就是g,如果第二个字符串位置上的字符在第一个字符串里出现过就是y,否则是r

按题意模拟。

点击查看代码
void solve() {
    std::string a, b;
    std::cin >> a >> b;
    std::vector<int> st(26);
    for (auto & c : a) {
    	st[c - 'a'] = 1;
    }

    std::string s;
    for (int i = 0; i < 8; ++ i) {
    	if (a[i] == b[i]) {
    		s += 'g';
    	} else if (st[b[i] - 'a']) {
    		s += 'y';
    	} else {
    		s += 'r';
    	}
    }

    std::cout << s << "\n";
    if (std::count(s.begin(), s.end(), 'g') != 8) {
    	std::cout << "defeat\n";
    } else {
    	std::cout << "congratulations\n";
    }
}

C. 智乃的数字

题意:3的倍数和5的倍数且是奇数的数是好的,求第k个好的数。

考虑二分,一个数x前面有多少个好数?就是看有多少3的倍数和多少5的倍数,但要减去同时使3和5的倍数的数,但这样还会算上偶数,那么就减去同时是2和3的倍数已经是2和5的倍数的数,即减去6的倍数和10的倍数。同样道理,多减去的要加回来,那么要加去同时是6和10倍数的数,即加上30的倍数。

点击查看代码
void solve() {
    i64 k;
    std::cin >> k;
    i64 l = 1, r = 1e18;
    while (l < r) {
    	i64 mid = l + r >> 1;
    	if (mid / 3 + mid / 5 - mid / 15 - mid / 6 - mid / 10 + mid / 30 >= k) {
    		r = mid;
    	} else {
    		l = mid + 1;
    	}
    }

    std::cout << l << "\n";
}

D. 智乃与长短期主义者博弈

题意:两个人玩一个数组,每次只能从两端拿,第一个人在左边的数大于等于右边的情况下拿左边的,否则拿右边的,第二个人可以自己决定拿左边的还是右边的。两个人都希望最后拿的数总和最大,求最终结果。

可以用f[l][r]表示剩下区间为[l,r]时第二个人可以取多少,记忆化搜索即可。

点击查看代码
void solve() {
    int n;
    std::cin >> n;
    std::vector<int> a(n);
    for (int i = 0; i < n; ++ i) {
    	std::cin >> a[i];
    }

    int sum = std::accumulate(a.begin(), a.end(), 0);

    std::vector f(n, std::vector<int>(n, -1));
    auto dfs = [&](auto self, int l, int r, int flag) -> int {
    	if (l > r) {
    		return 0;
    	}

    	if (f[l][r] != -1) {
    		return f[l][r];
    	}

    	int res = 0;
    	if (flag == 1) {
    		if (a[l] >= a[r]) {
    			res = std::max(res, self(self, l + 1, r, flag ^ 1));
    		} else {	
    			res = std::max(res, self(self, l, r - 1, flag ^ 1));
    		}
    	} else {
    		res = std::max(self(self, l + 1, r, flag ^ 1) + a[l], self(self, l, r - 1, flag ^ 1) + a[r]);
    	}

   		return f[l][r] = res;
    };

    int x = dfs(dfs, 0, n - 1, 1);
    std::cout << sum - x << " " << x << "\n";
}

E. 智乃的跳跃排序

题意:给你一个数组,每个元素互不相同。你可以交换每个下标差的绝对值等于k的元素或者值的差的绝对值等于k的元素。问能不能使数组升序。

先把模k相同的一起排序,然后把值的差的绝对值等于k的排序。检查是否是升序即可。

点击查看代码
void solve() {
    int n, k;
    std::cin >> n >> k;
    std::vector<int> a(n);
    for (int i = 0; i < n; ++ i) {
    	std::cin >> a[i];
    }

    auto b = a;
    std::sort(b.begin(), b.end());
    for (int i = 0; i < std::min(k, n); ++ i) {
        std::vector<int> c;
        for (int j = i; j < n; j += k) {
            c.push_back(a[j]);
        }

        std::sort(c.begin(), c.end());
        for (int j = i, l = 0; j < n; j += k) {
            a[j] = c[l ++ ];
        }
    }

    std::map<int, int> pos;
    for (int i = 0; i < n; ++ i) {
        pos[a[i]] = i;
    }

    for (int i = 0; i < n; ++ i) {
        int x = b[i];
        std::vector<int> p;
        while (pos.count(x) && pos[x] != -1) {
            p.push_back(pos[x]);
            pos[x] = -1;
            x += k;
        }

        std::sort(p.begin(), p.end());
        for (int j = 0; j < p.size(); ++ j) {
            a[p[j]] = j * k + b[i];
        }
    }

    if (a != b) {
        std::cout << "No\n";
    } else {
        std::cout << "Yes\n";
    }
}
posted @   maburb  阅读(38)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示