1.小苯的数字权值
#include <iostream>
#include <algorithm>
using namespace std;const int max_n = 2000000;
int d[max_n + 1];
int f[max_n + 1];int main() {for(int i =1; i<=max_n;i++){for(int j = i; j<=max_n;j+=i){d[j]++;}}for(int i=1; i<=max_n;i++){f[i] = d[i];}for(int i = 2; i <= max_n; i++){for(int j = 2; j <= max_n / i; j++){int k = i * j;if(f[i] + f[j] > f[k]){f[k] = f[i] + f[j];}}}int T;scanf("%d", &T);while(T--){int x;scanf("%d", &x);printf("%d\n", f[x]);}return 0;}
2.小红的子序逆序列
#include <iostream>
#include <vector>
#include <algorithm>using namespace std;const int MOD = 1e9 +7;class FenwickTree{
private:vector<int> tree;int size;public:FenwickTree(int n) : size(n), tree(n+1,0){}void update(int idx, int delta) {while(idx <= size){tree[idx] += delta;idx += idx & -idx;}}int query(int idx){int res = 0;while(idx > 0){res += tree[idx];idx -= idx & -idx;}return res;}
};int main(){int n;cin >> n;vector<int> a(n);for(int i=0;i<n;++i){cin >> a[i];}vector<int> temp = a;sort(temp.begin(), temp.end());temp.erase(unique(temp.begin(), temp.end()), temp.end());for(int i = 0; i<n;i++){a[i] = lower_bound(temp.begin(), temp.end(), a[i]) - temp.begin() + 1;}FenwickTree ft(temp.size());long long inv_count = 0;for(int i = n-1; i>=0;--i){inv_count += ft.query(a[i] - 1);ft.update(a[i], 1);}long long power = 1;for(int i =0; i < n-2; ++i){power = (power * 2)%MOD;}long long total = (inv_count % MOD) * (power % MOD) % MOD;cout << total << endl;return 0;
}// 64 位输出请用 printf("%lld")
3.小美的彩带
#include <iostream>
#include<bits/stdc++.h>
using namespace std;#define all(x) x.begin(), x.end() //
int n, q ,len, m, blo;char op;
int length;
int lisan[20005];
int a[400005], ans[200005];
int mp[200005], siz;
// 64 位输出请用 printf("%lld")struct stuct{int l, r, idx;bool operator< (const stuct& x) const{if(l/blo != x.l / blo) return l < x.l;return ( l / blo ) & 1 ? r > x.r : r < x.r;}} b[200005];int get(int v){return lower_bound(lisan +1, lisan +1 +m, v) - lisan;
}int main(){scanf("%d %d", &n, &q);for(int i=1; i<=n;++i){scanf("%d", &a[i]);lisan[i] = a[i];}sort(lisan +1, lisan + 1+ n);m = unique(lisan + 1, lisan + 1 + n) - lisan;--m;blo = sqrt( 2* n) * 1.5;for(int i = 1; i <= n; ++i){a[i] = get(a[i]);a[i+n] = a[i];}scanf("\n");int l = 1, r = 2*n, len = 0;for(int i = 1; i<=q;++i){scanf("%c %d\n", &op, &length);if(length >= n){ans[i] = m;length %= n;if(op =='L'){l += length;if(l>n) {l -= n;}}else{r -= length;if( r<= n) r+=n;}continue;}if(op =='L'){++len;b[len].l = l, b[len].r = l + length -1, b[len].idx = i;l+=length;if(l > n) l -= n;}else{++len;b[len].l = r - length + 1, b[len].r = r, b[len].idx = i;r -= length;if(r <= n) r += n;}}sort(b+1, b+1+len);l = 0, r = 0;for(int i = 1; i <= len; ++i){while( r < b[i].r){++r;if(mp[a[r]]==0) siz++;mp[a[r]]++;}while( r > b[i].r){mp[a[r]]--;if(mp[a[r]]==0)siz--;--r;}while( l < b[i].l){mp[a[l]]--;if(mp[a[l]] == 0) --siz;++l;}while( l > b[i].l){--l;if(mp[a[l]] == 0) ++siz;mp[a[l]]++;}ans[b[i].idx] = siz;}for(int i = 1; i<= q; ++i) printf("%d\n", ans[i]);return 0;
}
4.小美和大富翁
5.数组删除
#include <iostream>
#include <cstring>
#include <vector>
#include <string>
#include <set>
#include <unordered_set>
#include <unordered_map>
#include <cmath>
#include <queue>
#include <iomanip>
#include <algorithm>using namespace std;// 64 位输出请用 printf("%lld")unordered_map<long long, long long> hashMap;long long a[20005];void solve() {hashMap.clear();long long n, k, x;cin >> n >> k >> x;for(long long i = 1; i <= n; i++){cin >> a[i];hashMap[a[i]]++;}long long minMiss = 0;while(true){auto it = hashMap.find(minMiss);if(it == hashMap.end()){break;}minMiss++;}long long result = k * minMiss; for(long long i = 1; i <= n; i++){long long start =0;long long mex = -1;auto target = hashMap.find(a[i]);if(target -> second >= 2){hashMap[a[i]]--;}else{hashMap.erase(a[i]);}while(true){auto it = hashMap.find(start);if(it == hashMap.end()){mex = start;break;}start++;}result = min(result, i*x+k*mex);}cout << result << endl;
}int main() {std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);long long T = 1;cin >> T;while(T--){solve();}return 0;
}
6.数字删除
#include <string>
#include <iostream>
using namespace std;bool isValid(const string & s){if(s.empty() || s == "0") return false;int sum =0;for(char c:s) sum += c - '0';return sum % 3==0;
}int maxDelete(string s){int cnt =0;while(s.length() > 1){bool found = false;for(int i = 0; i< s.length(); i++){string t = s.substr(0,i) + s.substr(i+1);if(isValid(t)){s = t;cnt++;found = true;break;}}if(!found) break;}return cnt;
}int main(){int T;cin >> T;while(T--){string s;cin >> s;cout << maxDelete(s) << endl;}return 0;
}
// 64 位输出请用 printf("%lld")
7.小红的数字串
#include <iostream> // 引入输入输出流头文件
#include <string> // 引入字符串处理头文件
using namespace std;int main() {string s; // 存储输入的数字串long long k; // 存储输入的正整数kcin >> s >> k; // 读取输入int n = s.size(); // 获取数字串长度long long ans = 0; // 记录满足条件的子串数量int left = 0; // 预留变量,实际未使用long long num = 0; // 用于存储当前子串转换成的数字// 枚举每个子串的右端点for (int right = 0; right < n; ++right) {num = 0; // 每次外层循环重置num// 枚举以right为结尾的所有子串,长度最多为10(因为k最大为1e9,超过10位一定不小于k)for (int l = right; l >= 0 && right - l + 1 <= 10; --l) {num = stoll(s.substr(l, right - l + 1)); // 将子串转换为数字if (num < k) ans++; // 如果小于k,计数加一else break; // 如果不小于k,提前结束内层循环}}cout << ans << endl; // 输出满足条件的子串数量return 0; // 程序结束
}
8.小红的0 1串
/*
每遇到一个"010"或"101"子串,只需修改其中任意一个字符即可消除该子串。
为避免重叠,每次修改后跳过这3个字符。
时间复杂度O(n)。
*/
#include <iostream> // 引入输入输出流头文件
#include <string> // 引入字符串处理头文件
using namespace std;// 功能:将01串变为不含"010"和"101"子串的“好串”,返回最小操作次数
int main() {string s; // 定义字符串s,存储输入的01串cin >> s; // 读取输入的01串int n = s.size(); // 获取字符串长度int ans = 0; // 记录最小操作次数// 遍历字符串,检查每个长度为3的子串for (int i = 0; i <= n - 3; ) {// 如果当前位置出现"010"或"101"子串if ((s[i] == '0' && s[i + 1] == '1' && s[i + 2] == '0') ||(s[i] == '1' && s[i + 1] == '0' && s[i + 2] == '1')) {ans++; // 需要进行一次操作(取反其中任意一个字符即可消除该子串)i += 3; // 跳过这3个字符,防止重叠子串被重复计数} else {i++; // 如果不是"010"或"101",则继续检查下一个位置}}cout << ans << endl; // 输出最小操作次数return 0; // 程序结束
}
9. 小红的爆炸串2
/**
代码解释1.初始化:读入字符串长度 n、阈值 k 和字符串 s。2.滑动窗口:右指针 j:遍历字符串的每个位置。更新相邻对数:若 s[j−1] 和 s[j] 不同,则 cur_sum 加 1。调整左指针:当 cur_sum >= k 时,向右移动左指针 i,并减少离开窗口的字符对的贡献。3.计数:对每个 j,满足条件的子串数量为 j−i+1,累加到答案 ans。4.输出结果:打印所有不会爆炸的子串总数。*/#include <iostream> // 引入输入输出流头文件
#include <string> // 引入字符串处理头文件
using namespace std;int main() {ios::sync_with_stdio(false); // 关闭C++和C的流同步,加快输入输出速度cin.tie(0); // 解除cin和cout的绑定,加快输入输出int n, k; // n为字符串长度,k为爆炸的最小相邻不同对数string s; // 存储输入字符串cin >> n >> k; // 读取n和kcin >> s; // 读取字符串long long ans = 0; // 记录不会爆炸的子串数量int i = 0; // 滑动窗口左端指针int cur_sum = 0; // 当前窗口内相邻不同对数// 枚举右端点j,滑动窗口for (int j = 0; j < n; j++) {if (j >= 1) { // 不是第一个字符时if (s[j-1] != s[j]) {cur_sum++; // 如果当前字符和前一个字符不同,cur_sum加一}}// 如果窗口内不同对数达到k,移动左指针i缩小窗口while (i < j && cur_sum >= k) {if (s[i] != s[i+1]) {cur_sum--; // 移动i时,如果i和i+1不同,cur_sum减一}i++; // 左指针右移}ans += (j - i + 1); // 以j结尾的不爆炸子串数量累加到ans}cout << ans << endl; // 输出不会爆炸的子串数量return 0; // 程序结束
}
10. 小红的拼图
#include <iostream> // 引入输入输出流头文件
#include <vector> // 引入vector容器头文件
using namespace std;int main() {int t; // t为测试用例组数cin >> t;while (t--) { // 处理每组测试用例int n, m; // n为行数,m为列数cin >> n >> m;vector<string> grid(n); // 存储拼图网格for (int i = 0; i < n; i++) {cin >> grid[i]; // 读取每一行}bool found = false; // 标记是否存在合法拼接方案// 枚举W形状的四条边(上右下左)是凸(1)还是凹(0)for (int t0 = 0; t0 <= 1; t0++) {for (int r0 = 0; r0 <= 1; r0++) {for (int b0 = 0; b0 <= 1; b0++) {for (int l0 = 0; l0 <= 1; l0++) {// edges[i][j][k]表示(i,j)格子第k条边(0上1右2下3左)是凸(1)还是凹(0)vector<vector<vector<int>>> edges(n, vector<vector<int>>(m, vector<int>(4, -1)));bool valid = true; // 标记当前枚举的边形态是否有效// 根据每个格子的旋转形态,确定其四条边的凸凹情况for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {if (grid[i][j] == '*') continue; // 空格子跳过char c = grid[i][j];if (c == 'W') {edges[i][j] = {t0, r0, b0, l0}; // W: 上右下左} else if (c == 'D') {edges[i][j] = {l0, t0, r0, b0}; // D: 旋转90度} else if (c == 'S') {edges[i][j] = {b0, l0, t0, r0}; // S: 旋转180度} else if (c == 'A') {edges[i][j] = {r0, b0, l0, t0}; // A: 旋转270度}}}// 检查所有相邻格子的边是否契合for (int i = 0; i < n && valid; i++) {for (int j = 0; j < m && valid; j++) {if (grid[i][j] == '*') continue; // 空格子跳过// 检查右邻格子if (j + 1 < m && grid[i][j + 1] != '*') {// 当前格右边和右邻格左边之和必须为1(一个凸一个凹)if (edges[i][j][1] + edges[i][j + 1][3] != 1) {valid = false;}}// 检查下邻格子if (i + 1 < n && grid[i + 1][j] != '*') {// 当前格下边和下邻格上边之和必须为1if (edges[i][j][2] + edges[i + 1][j][0] != 1) {valid = false;}}}}// 如果当前枚举的边形态有效,说明存在合法拼接方案if (valid) {found = true;goto next; // 跳出所有循环,进入输出}}}}}next:if (found) {cout << "Yes" << endl; // 存在合法方案} else {cout << "No" << endl; // 不存在合法方案}}return 0;
}
11.小红的奇偶抽取
/**
该程序将输入的正整数的每一位数字,按奇偶性分别拼接成两个新数,然后输出这两个数的差的绝对值。
例如输入302938,奇数拼接为393,偶数拼接为28,输出|393-28|=365。
*/
#include <iostream> // 引入输入输出流头文件
#include <string> // 引入字符串处理头文件
using namespace std;int main() {string s; // 定义字符串s,用于存储输入的数字cin >> s; // 读取输入的数字串long long odd_num = 0; // 用于存储奇数位拼接成的数long long even_num = 0; // 用于存储偶数位拼接成的数// 遍历输入字符串的每个字符for (char c : s) {int digit = c - '0'; // 将字符转换为对应的数字if (digit % 2 == 1) { // 如果是奇数odd_num = odd_num * 10 + digit; // 拼接到奇数数值后面} else { // 如果是偶数even_num = even_num * 10 + digit; // 拼接到偶数数值后面}}long long diff = odd_num - even_num; // 计算奇数数和偶数数的差if (diff < 0) { // 如果差为负数diff = -diff; // 取绝对值}cout << diff << endl; // 输出最终结果return 0; // 程序结束
}