目录
开心果:
一道 n 皇后 的进阶题 ( 多了点条件
首先再复习一下 n 皇后的 dfs + 剪枝 + 回溯 解法:
解题: 按行暴力枚举可能放置皇后的列 , 逐层判断每列是否能放下皇后 , 不能则回溯到上一行.
class Solution {
private:
vector<string>Map;
vector<vector<string>>re;
bool cheak(int row , int col , int n){
for(int i = 0;i < row;i ++) if(Map[i][col] == 'Q') return false;
int r = row - 1 , c = col - 1;
while(r >= 0 && c >= 0){
if(Map[r][c] == 'Q') return false;
r -- , c --;
}
r = row - 1 , c = col + 1;
while(r >= 0 && c < n){
if(Map[r][c] == 'Q') return false;
r -- , c ++;
}
return true;
}
void dfs(int n , int row){
if(row == n){ re.push_back(Map); return; }
for(int col = 0;col < n;col ++){
if(cheak(row , col , n)) Map[row][col] = 'Q' , dfs(n , row + 1) , Map[row][col] = '.';
}
return;
}
public:
vector<vector<string>> solveNQueens(int n) {
string s(n , '.');
for(int i = 0;i < n;i ++) Map.push_back(s);
dfs(n , 0);
return re;
}
};
进阶版本:
ps: 比常规的 n皇后 多了 "每个皇后都能看到其她所有的皇后"; 即不存在在同一直线上的皇后.
解题: 就是cheak函数中再多加一个判断条件即可.
#include<bits/stdc++.h>
#define ios ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using namespace std;
const int N = 1000;
vector<int>nums(N , 0);
int n , cnt = 0;
void Print(int n){
for(int i = 1;i <= n;i ++){
if(i != 1) cout << ' ';
cout << nums[i];
}cout << endl;
}
bool cheak(int row , int col , int n){
for(int i = 1; i < row; i++)
if(nums[i] == col || abs(i - row) == abs(nums[i] - col))
return false;
for(int i = 1;i < row;i ++)
for(int j = row - 1;j > i;j --)
if((row - j) * (col - nums[i]) == (row - i) * (col - nums[j])) return false;
return true;
}
bool dfs(int n , int row){
if(cnt) return true;
if(row == n + 1){ Print(n) , cnt = 1; return true; }
for(int col = 1;col <= n;col ++){
if(cnt) return true;
if(cheak(row , col , n)) nums[row] = col , dfs(n , row + 1);
}
if(cnt) return true;
return false;
}
signed main(void){ios;
while(cin >> n && n){
cnt = 0;
nums.clear();
if(!dfs(n , 1)) cout << "Impossible!!!" << endl;
}
return 0;
}
离散数学:
第六章: 集合代数
6.2 集合的运算 :
集合的基本运算有并 , 交 , 相对补 和 对称差.
并:
交:
相对补:
对称差:
定义广义:
: A中所有的元素取并集.
: A中所有的元素取交集.
ps: 括号的优先级 > 广义 >
6.3 有穷集的计数 :
定义: 将集合进行计算 (有限个元素
包含排斥原理: (有限个集合元素
公式:
欧拉函数: (计算 n 以内与 x 互质数 的个数. P为质因数.
错排:
计算机组成原理:
算机的指令和运算,主要包含:
- 计算机指令:机器码(编译 -> 汇编 -> 机器码、指令格式和跳转、函数调用和程序栈)、程序的编译、链接、装载和执行;
- 计算机运算:二进制编码(整数、反码、补码、浮点数、定点数)、数字电路(门电路、加法器、乘法器);
leetcode每日一题:
题意: 在 数组 nums2 中 找到 每个数 右边第一个比它大的数 , 如果不存在就是 -1 , 然后按 数组nums1 排序输出 ( 满足 nums1 是 nums2 的子集.
数据不大 , 循环暴力
class Solution {
public:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
int n1= nums1.size() , n2 = nums2.size();
vector<int>re;
for(int i = 0;i < n1;i ++){
re.push_back(-1);
int j = 0;
while(j < n2 && nums2[j] != nums1[i]) j ++;
while(j < n2 && nums2[j] <= nums1[i]) j ++;
if(j < n2) re[i] = nums2[j];
}
return re;
}
};
解题关键就在划线部分 , 这就是一个标准单调栈的问题 (找到 每个数 右边第一个比它大的数) , 所以在构造好单调栈后 , 只需要把单调栈按 nums1 重新排序即可 ( 更优的解法是在构造单调栈的同时 , 利用哈希索引.
class Solution {
private:
unordered_map<int,int> u_map;
public:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
int n1 = nums1.size() , n2 = nums2.size();
vector<int>re;
for(int i = 0;i < n1;i ++) u_map[nums1[i]] = i , re.push_back(-1);
stack<int>sta;
for(int i = 0;i < n2;i ++){
while(!sta.empty() && nums2[i] > sta.top()){
int cnt = sta.top();
if(u_map.count(cnt)) re[u_map[cnt]] = nums2[i];
sta.pop();
}
sta.push(nums2[i]);
}
return re;
}
};
恰似草木对光阴.Day Four -- 酒醒花前坐.