算法|习题总结算法分析与计算复杂性在线测试Ⅰ

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++

以上是关于算法|习题总结算法分析与计算复杂性在线测试Ⅰ的主要内容,如果未能解决你的问题,请参考以下文章

算法设计与分析练习题

USTC算法设计与分析-总结

USTC算法设计与分析-总结

USTC算法设计与分析-总结

DFS算法(——模板习题与总结)

算法设计与分析——习题一