1.选择排序问题
简单来说,就是给了一串数,假如希望他们可以从小到大排列,
s / i=1(序号) | 2 | 3 | t / j =4 |
8 | 2 | 1 | 3 |
一开始,有一个判断条件,就是s<t,在这个条件之下进行判断
然后令i=s,j=t,让p=数组的一个中间值,通过p右边都比p大,左边都比p小进行判断
当i<=j是说明排序进行不彻底,如果这个时候,a[i]<p,i右移,同理,j左移
移完之后,如果i<=j,a[i],a[j]互换,并进行移位
(s) | i=j=2 | 3 | 4(t) |
1 | 2 | 8 | 3 |
然后此刻继续判断,因为满足i<t,j>s的条件,进行下一回的递归
最终得到正确答案
1 | 2 | 3 | 8 |
#include<bits/stdc++.h>
using namespace std;
int a[1110];
void qsort(int s, int t) {
if (s < t) {
int i = s, j = t;
int p = a[(i + j) / 2];
while (i <= j) {
while (a[i] < p) i++;
while (a[j] > p) j--;
if (i <= j) {
swap(a[i], a[j]);
i++, j--;
}
}
if (i < t) qsort(i, t);
if (j > s) qsort(s, j);
}
}
int main() {
int n; cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
qsort(1, n);
for (int i = 1; i <= n; i++) cout << a[i] << " ";
return 0;
}
2.全排列问题
就是比如输入3,把
1 2 3
1 3 2
2 1 3
2 3 1
3 2 1
3 1 2
这几种情况找出来
#include<bits/stdc++.h>
using namespace std;
int put[110];
int n,cnt;
bool st[110]; //如果这个数已经使用过了就变成1,没使用过就是0
void print(){
for(int i=1;i<=n;i++) cout<<put[i]<<" ";
cout<<endl;
}
void dfs(int i){
for(int j=1;j<=n;j++){
if(st[j]==0){
put[i]=j;
st[j]=1;//让他等于1是在这一次判断中已经出现的数不用再出现了
if(i==n){
cnt++;
print();
}
else dfs(i+1);
st[j]=0; //这个意思是在别的循环判断中还是要出现使用的,清理现场
}
}
}
int main(){
cin>>n;
dfs(1);
cout<<cnt;
return 0;
}
3.n皇后问题
#include<bits/stdc++.h>//n皇后
using namespace std;
const int N=50;
bool col[N],a[N],b[N];
int n,cnt;
int put[N];
void print(){
for(int i=1;i<=n;i++) cout<<put[i]<<" ";
cout<<endl;
}
void dfs(int i){
for(int j=1;j<=n;j++){
if(col[j]==0&&a[i+j]==0&&b[i-j+n]==0){
put[i]=j;
col[j]=1;
a[i+j]=1;
b[i-j+n]=1;
if(i==n){
cnt++;
print();
}
else dfs(i+1);
col[j]=0;
a[i+j]=0;
b[i-j+n]=0;
}
}
}
int main(){
cin>>n;
dfs(1);
cout<<cnt;
return 0;
}
4.hanoi问题
汉诺塔(又称河内塔)问题是印度的一个古老的传说。
开天辟地的神勃拉玛在一个庙里留下了三根金刚石的棒A、B和C,A上面套着n个圆的金片,最大的一个在底下,其余一个比一个小,依次叠上去,庙里的众僧不倦地把它们一个个地从A棒搬到C棒上,规定可利用中间的一根B棒作为帮助,但每次只能搬一个,而且大的不能放在小的上面。
僧侣们搬得汗流满面,可惜当n很大时这辈子恐怕就很搬完了。
聪明的你还有计算机帮你完成,你能写一个程序帮助僧侣们完成这辈子的夙愿吗?
###输入格式:
输入金片的个数n (1 <= n <= 10)。
###输出格式:
输出搬动金片的全过程。格式见样例。
###输入样例:
2
###输出样例:
Move disk 1 from A to B
Move disk 2 from A to C
Move disk 1 from B to C
#include<iostream>
#include<vector>
using namespace std;
//int n;
char a, b, c;//a经过b般到c
void hanoi(int n, char a, char b, char c) {
if (n == 1) {
cout << "Move disk " << n << " from " << a << " to " << c << endl;
return;
}
hanoi(n - 1, a, c, b);
cout << "Move disk " << n << " from " << a << " to " << c << endl;
hanoi(n - 1, b, a, c);
//cout << "Move disk " << n - 1 << " from B to C" << endl;
}
int main() {
int n;
cin >> n;
a = 'A', b = 'B', c = 'C';
hanoi(n, a, b, c);
}
5.二分查找
其实这道题比较简单的,就是根据a[mid]和k的大小,改变寻找的范围,注意一些边界条件的确定,比如一开始就判断i<j的话返回,不要把这个条件放在最后。
#include<iostream>
using namespace std;
const int N = 1000001;
int a[N];
int b_s(int a[],int s, int t, int k) {
int i = s, j = t,mid;
if (i > j)return -1;
if (i <= j) {
mid = (i + j) / 2;
if (a[mid] > k)
{
j = mid - 1;
b_s(a,s, j, k);
}
if (a[mid] < k) {
i = mid + 1;
b_s(a,i, t, k);
}
else if (a[mid] == k) return mid;
}
}
int main()
{
int n,k;
cin >> n>> k;
for (int i = 0; i < n; i++) {
cin >> a[i];
}
cout<<b_s(a, 0, n-1, k);
return 0;
}
//还有一种非递归的写法
int b_s(int a[],int s,int t,int k){
int low=s,high=t,mid;
while(low<=high){
mid=(low+high)/2;
if(a[mid]>k) high=mid-1;
if(a[mid]<k) low=mid+1;
else return mid;
}
return -1;
}