本篇题解只是记录我的做题过程代码,不提供最优解
(另外这里所有的时间复杂度都只分析单个样例,不算
t
t
t的时间复杂度)
A
点击此处查看对应的题目.
本题设计算法:模拟
直接将字符串向后推移一位即可。
时间复杂度 O ( n ) O(n) O(n)
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#include <cmath>
using namespace std;
typedef long long ll;
const ll N = 110;
int a[N];
int main()
{
string s;
cin >> s;
int n = s.size();
for (int i = 0;i < n;i ++ ) {
a[i + 1] = s[i] - '0';
}
a[0] = 0;
for (int i = 0;i < n;i ++ ) {
cout << a[i];
}
puts("");
return 0;
}
B
点击此处查看对应的题目.
本题设计算法:map统计
本题主要问题是判重,只要用个map统计字符串出现的次数就可以实现,但切记当一行字符串相同时,只能算一个,不然后面判断不出来。
时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn)
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#include <cmath>
using namespace std;
typedef long long ll;
const int N = 10010;
map<string,int> m;
string s[N],t[N];
int main()
{
int n;
cin >> n;
for (int i = 1;i <= n;i ++ ) {
string a,b;
cin >> a >> b;
s[i] = a,t[i] = b;
if (a == b) m[a] ++;
else m[a] ++,m[b] ++;
}
for (int i = 1;i <= n;i ++ ) {
string a = s[i],b = t[i];
if ((m[a] > 1 && m[b] > 1)) {
cout << "No" << '\n';
return 0;
}
}
puts("Yes");
return 0;
}
C
点击此处查看对应的题目.
本题设计算法:二叉树遍历
不难发现,本题的输出,遵循二叉树中序遍历的结果
时间复杂度 O ( 2 n ) O(2^n) O(2n)
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#include <cmath>
using namespace std;
typedef long long ll;
const int N = 10010;
int n;
void dfs(int u)
{
if (u == 0) return;
dfs(u - 1);
cout << u << ' ';
dfs(u - 1);
}
int main()
{
cin >> n;
dfs(n);
puts("");
return 0;
}
D
点击此处查看对应的题目.
本题设计算法:队列
本题的要求大致是要从后添加球,从前取出去球。
所以,从本题的要求可以看出,这符合队列的特性,我们可以用队列来实现这一系列的操作。
时间复杂度 O ( q ∗ ( c / d ) ) O(q * (c / d)) O(q∗(c/d))
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#include <queue>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PLL;
const int N = 10010;
queue<PLL> qe;
ll q,l,r;
int main()
{
cin >> q;
while (q -- ) {
ll op,x,c;
cin >> op;
if (op == 1) {
cin >> x >> c;
qe.push({c,x});
}else {
cin >> c;
ll sum = 0;
while (c) {//从队列前端向后取球,直到将c取完为止
ll d = min(c,qe.front().first);
sum += 1ll * d * qe.front().second;
qe.front().first -= d;
c -= d;
if (!qe.front().first) qe.pop();
}
cout << sum << '\n';
}
}
return 0;
}
E
点击此处查看对应的题目.
本题设计算法:状态压缩dp
本题我采用了 dls 的代码,思路已经都写在代码里了。详细见代码注释。
时间复杂度 O ( 4 ∗ n ) O(4 * n) O(4∗n)
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10,INF = 1e9;
ll dp[N][2][2];//表示前i个数(以第i个数结尾),是否出现过x或是是否出现过y的所有方案数量
int n,x,y;
int a[N];
int main()
{
scanf("%d%d%d",&n,&x,&y);
for (ll i = 1;i <= n;i ++ ) scanf("%d",&a[i]);
ll res = 0;
for (int i = 1;i <= n;i ++ ) {
if (a[i] > x || a[i] < y) continue;//排除不在区间范围的数
int is_x = (a[i] == x),is_y = (a[i] == y);
dp[i][is_x][is_y] ++;
//当前状态的与过去状态取并集
for (int j = 0;j < 2;j ++ ) {
for (int k = 0;k < 2;k ++ ) {
dp[i][is_x | j][is_y | k] += dp[i - 1][j][k];//只要过去的状态或当前的状态有1,那么当前的状态就是1
}
}
res += dp[i][1][1];
}
/*
for (int i = 1;i <= n;i ++ ,puts("")) {
for (int j = 0;j < 2;j ++ ) {
for (int k = 0;k < 2;k ++ ) {
cout << dp[i][j][k] << ' ';
}
}
}
*/
printf("%lld\n",res);
return 0;
}