算法|习题总结算法分析与计算复杂性在线测试Ⅰ
Posted 海轰Pro
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法|习题总结算法分析与计算复杂性在线测试Ⅰ相关的知识,希望对你有一定的参考价值。
目录
前言
Hello!
非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出~
自我介绍 ଘ(੭ˊᵕˋ)੭
昵称:海轰
标签:程序猿|C++选手|学生
简介:因C语言结识编程,随后转入计算机专业,获得过国家奖学金,有幸在竞赛中拿过一些国奖、省奖…已保研。
学习经验:扎实基础 + 多做笔记 + 多敲代码 + 多思考 + 学好英语!
唯有努力💪
知其然 知其所以然!
本文仅记录自己感兴趣的内容
题目一
内容
奇数数列求和
下面是奇数的数列:
1,3,5,7,9,…
请编写程序,输入奇数数列的项数 n,求奇数数列前 n 项的和 s。
输入格式
n
输出格式
s
输入样例
2
输出样例
4
注:题目保证 n 和 s 的值都在 long long int 类型的表示范围内。
参考Demo
#include<iostream>
using namespace std;
int main()
long long n ;
cin >> n;
cout << n * n << endl;;
return 0;
题目二
内容
计科Z支书为了讲解遍历算法,专门买了三个容量分别为A,B,C的水瓶。开始时A,B水瓶为空,而C装满水。可以把水从一个水瓶倒入另一个水瓶,但每次必须把倒出的水瓶倒空或者把倒入的水瓶装满。
求当水瓶A为空的时候,C水瓶中剩下的所有水量。
输入格式:
单独的一行包括三个整数 A,B 和 C (1≤A,B,C≤40)。
输出格式:
只有一行,列出当A 是空的时候,水瓶C中装有的所有水量,按水量升序排列输出。
数字间用空格分开,同时第一个数字前面和最后一个数字后面不能留空格。
输入样例:
8 9 10
输出样例:
1 2 8 9 10
注:比如把C中的水倒出8至A,剩下的2倒入B,再把A中的水全部倒入C,则C中留有水量8。
参考Demo
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
int temp[1001], ont = 0;
int arr[41][41][41];
int A, B, C;
void dfs(int a, int b, int c)
if (!arr[a][b][c])
arr[a][b][c] = 1;
if (a == 0)
temp[ont++] = c;
if (a)
if ((a + b <= B && !arr[0][a + b][c]) || (a - B + b >= 0 && !arr[a - B + b][B][c]))
dfs(max(0, a - B + b), min(a + b, B), c);
if ((a + c <= C && !arr[0][b][a + c]) || (a - C + c >= 0 && !arr[a - C + c][b][C]))
dfs(max(0, a - C + c), b, min(C, c + a));
if (b)
if ((a + b <= A && !arr[a + b][0][c]) || (b - A + a >= 0 && !arr[A][b - A + a][c]))
dfs(min(A, a + b), max(0, b - A + a), c);
if ((c + b <= C && !arr[a][0][b + c]) || (b - C + c >= 0 && !arr[a][b - C + c][C]))
dfs(a, max(0, b - C + c), min(C, c + b));
if (c)
if ((b + c <= B && !arr[a][c + b][0]) || (C - B + b >= 0 && !arr[a][B][C - B + b]))
dfs(a, min(c + b, B), max(0, c - B + b));
if ((a + c <= C && !arr[a + c][b][0]) || !arr[A][b][c - A + a])
dfs(min(A, a + c), b, max(0, c - A + a));
int main()
cin >> A >> B >> C;
memset(temp, 0, sizeof(temp));
memset(arr, 0, sizeof(arr));
dfs(0, 0, C);
sort(temp, temp + ont);
for (int i = 0; i < ont - 1; i++)
cout << temp[i] << " ";
cout << temp[ont - 1] << endl;
return 0;
题目三
内容
如下的 6 x 6 的棋盘,有六个棋子(皇后)被放置在棋盘上,使得每行、每列、每条对角线(包括 两条主对角线的所有对角线)上都至多有一个棋子。
上面的布局可以用序列 2 4 6 1 3 5 来描述,第 i 个数字表示在第i 行的相应位置有一个棋子(1≤i≤6),如下:
行号 1 2 3 4 5 6
列号 2 4 6 1 3 5
这只是跳棋放置的一个解,找出所有跳棋放置的解,并把它们以上面的序列方法输出。 解按字典顺序排列,输出前 3 个解,最后一行是解的总个数。
输入格式:
一个数字 N (6≤N≤13) 表示棋盘是 N×N 大小的。
输出格式:
前三行为前三个解,每个解的两个数字之间用一个空格隔开,第四行只有一个数字表示解的总数。
输入样例:
在这里给出一组输入。例如:
6
输出样例:
在这里给出相应的输出。例如:
2 4 6 1 3 5
3 6 2 5 1 4
4 1 5 2 6 3
4
参考Demo
#include<iostream>
#include<vector>
#include<unordered_set>
using namespace std;
vector<string> generateBoard(vector<int> &queens, int n)
auto board = vector<string>();
for (int i = 0; i < n; i++)
string row = string(n, '.');
row[queens[i]] = 'Q';
board.push_back(row);
return board;
void backtrack(vector<vector<string> > &solutions, vector<int> &queens, int n, int row, unordered_set<int> &columns, unordered_set<int> &diagonals1, unordered_set<int> &diagonals2)
if (row == n)
vector<string> board = generateBoard(queens, n);
solutions.push_back(board);
else
for (int i = 0; i < n; i++)
if (columns.find(i) != columns.end())
continue;
int diagonal1 = row - i;
if (diagonals1.find(diagonal1) != diagonals1.end())
continue;
int diagonal2 = row + i;
if (diagonals2.find(diagonal2) != diagonals2.end())
continue;
queens[row] = i;
columns.insert(i);
diagonals1.insert(diagonal1);
diagonals2.insert(diagonal2);
backtrack(solutions, queens, n, row + 1, columns, diagonals1, diagonals2);
queens[row] = -1;
columns.erase(i);
diagonals1.erase(diagonal1);
diagonals2.erase(diagonal2);
vector<vector<string> > solveNQueens(int n)
auto solutions = vector<vector<string> >();
auto queens = vector<int>(n, -1);
auto columns = unordered_set<int>();
auto diagonals1 = unordered_set<int>();
auto diagonals2 = unordered_set<int>();
backtrack(solutions, queens, n, 0, columns, diagonals1, diagonals2);
return solutions;
int main()
int n ;
cin >> n;
vector<vector<string> > a = solveNQueens(n);
for(int i = 0; i < 3; ++i)
vector<int> temp(n);
for(int j = 0; j < a[i].size(); ++j)
temp[j] = a[i][j].find('Q') + 1;
for(int k = 0; k < temp.size() - 1; ++ k)
cout << temp[k] << " ";
cout << temp[temp.size() - 1] ;
cout << endl;
cout << a.size() << endl;
return 0;
暴力取巧:最后两个测试用例一个是n=12一个是n=13,直接return即可
题目四
内容
由相同数量的左括号’(‘和右括号’)'构成的字符串,只需要将一定长度(可以为0)的前缀移动到字符串的末尾,就可以使其中的左右括号匹配成功,即成为括号语句。在这里,我们不用数学方法去证明该命题的正确性,而是编程求出所有可行的前缀长度。
输入格式:
- 输入在一行中给出由’(‘和’)'构成的字符串,长度不超过 1 0 6 10^6 106 。
- 题目保证字符串中左右括号的数量相同。
输出格式:
- 在一行中输出所有可行的前缀长度,按升序排列。
- 数值间用空格分开,末尾的值后面没有空格。
输入样例:
(()))))()(())((()))()(((
输出样例:
7 9 13 19 21
注:上述长度的前缀各自移动到末尾后得到的括号语句如下:
长度7: ()(())((()))()((((()))))
长度9: (())((()))()((((()))))()
长度13:((()))()((((()))))()(())
长度19:()((((()))))()(())((()))
长度21:((((()))))()(())((()))()
参考Demo - 1
#include <cstdlib>
#include <iostream>
#include <queue>
#include <stack>
using namespace std;
bool isQTrue(vector<char>& q)
if (q.size() == 0)
return true;
stack<char> stack;
for (int i = 0; i < q.size(); i++)
char c = q[i];
if (c == '(')
stack.push(c);
if (c == ')')
if (stack.empty())
return false;
char one = stack.top();
if (c == ')' && one != '(')
return false;
stack.pop();
if (!stack.empty())
return false;
return true;
int main()
vector<char> q;
int flag = 0;
string s;
cin >> s;
for (int i = 0; i < s.length(); i++)
q.push_back(s[i]);
if (isQTrue(q))
cout << 0;
flag = 1;
for (int i = 1; i < s.length(); i++以上是关于算法|习题总结算法分析与计算复杂性在线测试Ⅰ的主要内容,如果未能解决你的问题,请参考以下文章