牛客寒假基础训练1
官方题解地址:https://ac.nowcoder.com/acm/contest/9981
####A
题意:输出所有含有子序列"us"并且长度为n的字符串
计数dp:
由于当dp[i][2]不为0时,dp到当前位置刚好存在us两个字符,因此不存在冲突现象
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 1000010, mod = 1e9 + 7;
typedef long long ll;
int n;
ll dp[N][3];
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n;
dp[0][0] = 1;
for(int i = 1; i <= n; i++) {
dp[i][0] = (dp[i - 1][0] * 25) % mod;
dp[i][1] = (dp[i - 1][0] + dp[i - 1][1] * 25) % mod;
dp[i][2] = (dp[i - 1][1] + dp[i - 1][2] * 26) % mod;
}
ll res = 0;
for(int i = 1; i <= n; i++) res = (res + dp[i][2]) % mod;
cout << res << '\n';
return 0;
}B
构造刚好为k的括号匹配,并使最终字符串的长度在100000以内。
假如字符串的构造形式像这样:()()()()
令n为完整括号形式,上面这个的n = 4
那么所能构造的括号匹配数量为
自然还会剩下一些,那么在剩下的内些数量的括号位置加上一个)即可
比如要构造13个匹配,而()()()()只能构造12给匹配,那么在第一对括号后面加上一个)即可
即:())()()()
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
long long k, n = 1;
cin >> k;
if(!k) {
cout << "(" ;
return 0;
}
while(n * n + n <= 2 * k) {
n++;
}
n--;
long long tmp = k - (n * n + n) / 2;
string res;
for(int i = 1; i <= n; i++)
if(i == tmp) {
res += "())";
cout << "())";
}
else {
res += "()";
cout << "()";
}
return 0;
}F
最大的即为相同的个数 * 2 + 不同个数,最下为0
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 110;
int n;
char a[N], b[N];
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n;
for(int i = 0; i < n; i++) cin >> a[i];
for(int i = 0; i < n; i++) cin >> b[i];
int cnt = 0;
for(int i = 0; i < n; i++)
if(a[i] == b[i]) cnt++;
cout << n + cnt << ' ' << 0 << '\n';
return 0;
}I
由于k <= n / 2,并且偶数为n / 2个,那么能构成k-1个gcd为2的序列,最后再在末尾添加一个能整除该末尾偶数的数即可
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 100010;
bool vis[N];
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n, k;
cin >> n >> k;
vector<int> res;
if(n <= 3) {
if(k) cout << -1;
else for(int i = 1; i <= n; i++) cout << i << ' ';
return 0;
}
if(n == 4) {
if(k == 1) cout << "1 2 4 3";
else if(k == 0) cout << "1 2 3 4";
else cout << -1;
return 0;
}
if(n == 5) {
if(k == 1) cout << "1 2 4 3 5";
else if(k == 0) cout << "1 2 3 4 5";
else cout << -1;
return 0;
}
if(k == n / 2) {
for(int i = 2, j = 0; j < k; j++, i += 2) {
res.push_back(i);
vis[i] = true;
}
for(int i = 3; i <= n; i += 2) {
if(res.back() % i == 0) {
res.push_back(i);
vis[i] = true;
break ;
}
}
for(auto x : res) cout << x << ' ';
for(int i = 1; i <= n; i++) if(!vis[i]) cout << i << ' ';
} else {
for(int i = 2, j = 0; j <= k; j++, i += 2) {
res.push_back(i);
vis[i] = true;
}
for(auto x : res) cout << x << ' ';
for(int i = 1; i <= n; i++) if(!vis[i]) cout << i << ' ';
}
return 0;
}C
转载他人做法https://blog.nowcoder.net/n/32e7a9e7caa3422286109ab0b3fabf37
#include <iostream>
#include <cstring>
using namespace std;
const int N = 100010, M = N << 1;
int n;
int h[N], e[M], ne[M], idx;
int f[N], col[N], cnt;
bool ok = true;
void add(int a, int b) {
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
void dfs1(int u, int fa) {
for(int i = h[u]; ~i; i = ne[i]) {
int j = e[i];
if(j == fa) continue ;
dfs1(j, u);
}
if(!f[u]) {
if(fa == -1 || f[fa]) ok = false;
f[fa] = f[u] = ++cnt;
}
}
void dfs2(int u, int fa) {
for(int i = h[u]; ~i; i = ne[i]) {
int j = e[i];
if(j == fa) continue ;
if(f[j] == f[u]) col[j] = col[u];
else col[j] = col[u] ^ 1;
dfs2(j, u);
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
memset(h, -1, sizeof h);
cin >> n;
for(int i = 0, a, b; i < n - 1; i++) {
cin >> a >> b;
add(a, b), add(b, a);
}
dfs1(1, -1);
if(!ok) {
cout << -1 << '\n';
return 0;
}
col[1] = 1;
dfs2(1, -1);
for(int i = 1; i <= n; i++)
if(col[i]) cout << 'B';
else cout << 'R';
return 0;
}J
LCM的组合一定是质数的最高次幂,因此考虑求质数的最高次幂
对于2来说,其能贡献的最高次幂为k,那么最终应该是 其中k为最大的次幂,贡献为2的k次幂
对于大于2的质数应满足k, 贡献为p的k次幂
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 80010000, mod = 1e9 + 7;
typedef long long ll;
int n;
bool vis[N];
int prime[5000010], cnt;
void init() {
for(int i = 2; i < N; i++) {
if(!vis[i]) prime[cnt++] = i;
for(int j = 0; 1ll * i * prime[j] < N ; j++) {
vis[prime[j] * i] = true;
if(i % prime[j] == 0) break ;
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
init();
cin >> n;
if(n < 6) {
cout << "empty" << '\n';
return 0;
}
ll res = 1;
for(int i = 0; i < cnt && prime[i] <= n / 2; i++) {
int p = prime[i];
if(p == 2) {
ll tmp = 1;
while(tmp * p <= n / 3) tmp *= p;
res = res * tmp % mod;
} else {
ll tmp = 1;
while(tmp * p <= n / 2) tmp *= p;
res = res * tmp % mod;
}
}
cout << res << '\n';
return 0;
}