At grand 022 GCD序列构造 dp/floyd二进制变换最少费用
A
diverse words指的是每一个字母在单词中出现的次数不超过1的单词
题目要求你求出字典序比当前给定单词大的字典序最小单词
1.如果给定的单词长度小于26 就遍历一次在单词尾部加上字典序最小的一个字母
2.如果单词的长度等于26 当且仅当单词为 zyxwvutsrqponmlkjihgfedcba 时没有答案 我们从最后一个字母开始消除如果到一个字母有比他大的就替换掉
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #define TS printf("!!!\n") #define pb push_back #define inf 1e9 //std::ios::sync_with_stdio(false); using namespace std; //priority_queue<int,vector<int>,greater<int>> que; get min const double eps = 1.0e-10; typedef pair<int, int> pairint; typedef long long ll; typedef unsigned long long ull; //const int maxn = 3e5 + 10; const int maxn = 100005; const int turn[4][2] = {{1, 0}, { -1, 0}, {0, 1}, {0, -1}}; //priority_queue<int, vector<int>, less<int>> que; //next_permutation int zimu[30]; int sum = 0; map<char, int> mp; int main() { string now; cin >> now; string ans = ""; for (int i = 0; i < now.size(); i++) { zimu[now[i] - 'a']++; } if (now.size() < 26) { cout << now; for (int i = 0; i <= 25; i++) { if (!zimu[i]) { cout << (char)('a' + i); return 0; } } } for (int i = now.size() - 1; i >= 0; i--) { int cnt = now[i] - 'a'; for (int j = cnt + 1; j <= 25; j++) { if (!zimu[j]) { for (int k = 0; k < i; k++) { cout << now[k]; } cout << (char)('a' + j); return 0; } } zimu[now[i] - 'a']--; } cout << -1 << endl; }
B
要求你构造一个序列 序列总和与每一项的GCD不等于1 但总GCD为1 所有数不能超过300000
题目案例有提示 但是还是要你自己推 最后满足要求的只能是2,3两个数 2,3的LCM为6所以我们的序列总和一定要是6的倍数
我们把2的倍数三个为一组 这样就是6的倍数 3的倍数两个为一组 这样也是6的倍数
第一种情况:当N%3==0 即取2的倍数三个为一组可以全部取完的时候 去掉两组给3的倍数 这样才使总GCD为1
第二种情况:当N%3不为0 为2的时候 我们直接取一组3的倍数即可满足条件 为1的时候全部取3的倍数的话总和为6*N+3 我们需要消去这个3 需要再加一个3的倍数 又因为3的倍数是6*M+3 所以我们需要消去2的倍数里面的一个6的倍数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> #include <algorithm> #include <vector> using namespace std; typedef long long ll; int main() { int n; cin >> n; if (n == 3) { cout << "2 5 63" << endl; return 0; } if (n == 6) { cout << "2 4 6 12 3 9" << endl; return 0; } int two = n / 3; if (two > 5000) { two = 5000; } else { if (n % 3 == 0) { two -= 2; } } int number2 = two * 3 - ((n - two * 3) % 2 == 1); int number3 = n - number2; for (int i = 1; i <= number2; i++) { cout << 2 * i << " "; } for (int i = 1; i <= number3; i++) { cout << (2 * i - 1) * 3 << " "; } cout << endl; }