比赛跑路太早,一听题解就好气,感觉本不该这么菜,所以以后跑路会慢些 !
代码参考了好多人,雨巨,大佬xxx,感谢。
大部分代码是参考 雨巨,特别感谢QwQ
水平有限,题解供参考
官方题解:https://ac.nowcoder.com/discuss/593200
目前已经写的是A,B,F,H,I,J(2021/2/2)
A 串
题目链接:https://ac.nowcoder.com/acm/contest/9981/A
题目思路:分析如图:
AC代码
#include<iostream>
using namespace std;
const int N = 2e6 + 10;
const int p = 1000000007;
int n;
long long f[N][3];
int main()
{
cin >> n;
f[1][1] = 1;f[1][2] = 25;
long long ans = 0;
for(int i = 2;i <= n;i ++)
{
f[i][0] = (f[i - 1][0] * 26 % p + f[i - 1][1]) % p;
f[i][1] = (f[i - 1][1] * 25 % p + f[i - 1][2]) % p;
f[i][2] = f[i - 1][2] * 25 % p;
ans = (ans + f[i][0]) % p;
}
cout << ans;
return 0;
}
参考雨巨 ,感觉空间上可以继续优化, 这个日后更新,flag ++;
空间上优化,列出状态转移方程。
why?
分俩两种:第一种,如果前面包含us,直接随便上一个字母.
f[i] = f[i - 1] * 26; ①
第二种,如果前面不包含us,但是包含u,上一个s,就可以。
方案数 = 26 ^ (i - 1) - 25 ^ (i - 1) - f[i - 1];②
① + ②,得状态转移方程。
虽然空间复杂度降低了不少,但是 26 的 (i - 1) 次方 ,25 的 (i - 1) 次方,这个需要快速幂求解。
B 括号
题目链接:https://ac.nowcoder.com/acm/contest/9981/B
题目思路:比赛的时候只过了
80
80
80%,debug了好久终于只过
75
75
75%(喵喵喵?)
AC代码:
#include<cmath>
#include<iostream>
using namespace std;
int main()
{
int k;
cin >> k;
int a = k / 50000;
for(int i = 0;i < a;i ++)cout << "(";
int b = k % 50000;
for(int i = 50000;i >= 1;i --)
{
if(i == b) cout << "(";
cout << ")";
}
return 0;
}
OK,下面来分析为什么我的又臭又长 的代码,为什么只能过
75
75
75%
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
int n;
cin >> n;
int x = sqrt(n);
//定义d是差了几个
int d = n - x * x;
// 0 特殊判断一下
if(n == 0)puts(")(");
else if(d == 0)
{
//d == 0 说明正好左边 x 个 右边 x 个;
for(int i = 0;i < x;i ++)cout << "(";
for(int i = 0;i < x;i ++)cout << ")";
}
else if(n < 99999)
{
cout << "(";
for(int i = 0;i < n;i ++)cout<< ")";
}
else {
for(int i = 0;i < x;i ++)cout << "(";
for(int i = 0;i < x - d;i ++)cout << ")";
cout << "(";
for(int i = 0;i < d;i ++)cout << ")";
}
return 0;
}
错在了最后一个 e l s e else else 这里,思考一下,如果是 15 15 15(虽然15 不会到最后一个 e l s e else else,但是这里是举例子)的话, s q r t = 3 sqrt = 3 sqrt=3,意思是后面剩下 3 3 3个反括号,但是 d d d 缺差了 6 6 6,凑不出来。
C 红和蓝
D 点一成零
E 三棱锥之刻
F 对答案一时爽
题目链接:https://ac.nowcoder.com/acm/contest/9981/F
题目思路:最小一定是
0
0
0,最大是
n
n
n + 选择重复的个数。
AC代码
#include<bits/stdc++.h>
#define PI acos(-1)
#define endl "\n"
#define mm(a, b) memset(a, b, sizeof(a))
#define debug freopen("1.in", "r", stdin), freopen("1.out", "w", stdout);
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
typedef long long ll;
typedef pair<int , int> PII;
const int N = 200;
int n;
char a[N],b[N];
int main()
{
ll res = 0;
cin >> n;
for(int i = 0;i < n;i ++)cin >> a[i];
for(int i = 0;i < n;i ++)
{
cin >> b[i];
if(a[i] == b[i])res ++;
}
res = res + n;
//for(int i = 0 ;i < n ;i ++)cout << a[i] << endl;
cout << res << " " << "0" << endl;
return 0;
}
G 好玩的数字游戏
H 幂塔个位数的计算
题目链接:https://ac.nowcoder.com/acm/contest/9981/H
题目思路:
思路2分析:
如果个位是0,幂多少次个位都是0。
如果个位是1,幂多少次个位都是1。
如果个位是2,2 4 6 8·····循环。
如果个位是3,3,9,7,1······循环。
如果个位是4,4,6·····循环。
如果个位是5,幂多少次都是5。
如果个位是6,幂多少次都是6。
如果个位是7,7,9,3,1······循环。
如果个位是8,8,4,2,6······循环。
如果个位是9,9,1······循环。
所以,如果是0 , 1, 5, 6,特判即可。
如果是 2 : a^a^ ,只需要判断 a % 4的大小,因为a结尾是2,所以a一定是个偶数, % 4只有两种结果,一种是2,一种是0,如果是2,输出4,如果是0,输出8.
如果 是 a^x^,x = a^a^,那么只有一种情况,因为 a 是个偶数,那么a 的 a 次方一定能整除4.
8则同2:如果个位是8,a % 4 可以取 0,2。 如果是 a^a^ % 4, 一定是0。
如果是3:a % 4 ,要么取3,要么取1。如果a % 4 = 3,那么如果a 幂了 奇数个 a 对 4 取模,答案依然是3,同理:a % 4 = 1,那么如果a 幂了 奇数个 a 对 4 取模,答案依然是1。
7则与3分析相似,但是相反:如果a % 4 = 3,那么如果a 幂了 奇数个 a 对 4 取模,答案是1·······
现在还剩下4,9.
如果是4的话,因为4是偶数,% 2 一定是0,始终是6.
如果是9,% 2 一定是 1,始终是9.
OK分析完毕,学欧拉降幂的奇怪动力增加了。
AC代码:
#include<iostream>
#include<cstring>
#include<string.h>
using namespace std;
int a, b;
string s1, s2;
int main()
{
cin >> s1 >> s2;
// 如果是 1次方,直接输出个位。
if(s2 == "1"){cout << s1[s1.size() - 1];return 0;}
a = s1[s1.size() - 1] - '0';
b = ((s1[s1.size() - 2] - '0') * 10 + (s1[s1.size() - 1] - '0')) % 4;
if(a == 0 || a == 1 || a == 5 || a == 6 || a == 9)cout << a;
if(a == 4) cout << 6;
if(a == 2 || a == 8)
{
if(s2 == "2" && b != 0) cout << 4;
else cout << 6;
}
if(a == 3)
{
if(b == 1) cout << 3;
else cout << 7;
}
if(a == 7)
{
if(b == 3)cout << 3;
else cout << 7;
}
return 0;
}
I 限制不互素对的排列
题目链接:https://ac.nowcoder.com/acm/contest/9981/I
题目思路:确实,在限定了
k
<
=
n
/
2
k <= n / 2
k<=n/2的情况下,题目简单了许多,只需要把情况分成两种,第一种
k
<
n
/
2
k < n / 2
k<n/2 第二种
k
=
n
/
2
k = n / 2
k=n/2,第一种,只用部分偶数就能解决问题,但是在第二种的时候可以用6 后面接 3 来凑到
n
/
2
n / 2
n/2,当
n
<
6
n < 6
n<6 的时候,只能由偶数来凑 k 对,如果凑不到,就返回
−
1
-1
−1.
AC代码:
#include<iostream>
using namespace std;
int n, k;
int main()
{
cin >> n >> k;
if (n < 6 && k == n / 2)
{
cout << -1;
return 0;
}
if (k < n/2)
{
int i = 2;
for(int j = 0;j < k + 1;j ++,i = i + 2) cout << i << " ";
i = i - 2;
for(int j = i + 1;j <= n;j ++)cout << j << " ";
for(int j = 1;j <= i;j = j + 2) cout << j << " ";
}
else
{
int i = 8;
for (int j = 0; j < k - 2; j ++, i = i + 2) cout << i << " ";
cout << 2 <<' '<< 4 <<' '<< 6 <<' ';
cout << 3 <<' '<< 1 <<' ';
for (int i = 5; i <= n; i = i + 2) cout << i <<" ";
}
return 0;
}
J 一群小青蛙呱蹦呱蹦呱
题目链接:https://ac.nowcoder.com/acm/contest/9981/J
题目思路:明天再写,数学好难QAQ。
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 160000000;
const int p = 1000000007;
int n;
int primes[N], cnt;
bool st[N];
long long ksm(int a, int b)
{
long long ans= 1, t= a;
while(b)
{
if (b & 1) ans = ans * t % p;
t = t * t % p;
b >>= 1;
}
return ans;
}
long long solve(int x)
{
if (x == 2)
return ksm(2, floor(log(n/3)/ log(2)));
return ksm(x, floor(log(n/2)/ log(x)));
}
int main()
{
cin >> n;
ll res = 1;
for (int i = 2; i <= n / 2; i ++ )
{
if (!st[i])
{
//cout << ksm(2,i) <<endl;
primes[cnt ++ ] = i;
res = (res * solve(i)) % p;
}
for (int j = 0;primes[j] <= n / i * 2; j ++ )
{
st[primes[j] * i] = true;
if (i % primes[j] == 0) break;
}
}
if(res == 1) cout << "empty";
else cout << res;
}