【算法实验】算法分析与设计第一次实验Lab1

第1关:二分查找

描述
给定一个单调递增的整数序列,问某个整数是否在序列中。

输入
第一行为一个整数n,表示序列中整数的个数;第二行为n(n不超过10000)个整数;第三行为一个整数m(m不超过50000),表示查询的个数;接下来m行每行一个整数k。

输出
每个查询的输出占一行,如果k在序列中,输出Yes,否则输出No。

输入样例
5
1 3 4 7 11
3
3
6
9

输出样例
Yes
No
No

#include <iostream>
using namespace std;
int tsearch(int arr[], int x, int left, int right)
{
    if(left > right)
        return -1;
    int mid = (left + right) / 2;
    if(x < arr[mid])
    {
        return tsearch(arr, x, left, mid - 1);
    }
    else if(x > arr[mid])
    {
        return tsearch(arr, x, mid + 1, right);
    }
    else
    {
        return mid;
    }
}

int main()
{
    int n, m, r, i = 0;
    int arr[10000], search[50000];
    cin >> n;
    for(i = 0; i < n; i++)
    {
        cin >> arr[i];
    }
    cin >> m;
    for(i = 0; i < m; i++)
    {
        cin >> search[i];
    }
    for(i = 0; i < m; i++)
    {
        r = tsearch(arr, search[i], 0, n - 1);
        if(r == -1)
            cout << "No" << endl;
        else
            cout << "Yes" << endl;
    }
    return 0;
}

第2关:归并排序

描述
给定一个数列,用归并排序算法把它排成升序。

输入
第一行是一个整数n(n不大于10000),表示要排序的数的个数;
下面一行是用空格隔开的n个整数。

输出
输出排序后的数列,每个数字占一行。

输入样例
5
3 2 1 4 5

输出样例
1
2
3
4
5

#include <iostream>
using namespace std;

void merge(int a[], int low, int mid, int high)
{
    int* tmp = new int[high - low + 1];
    int i = low, j = mid + 1, k = 0;
    while(i <= mid && j <= high)
    {
        if(a[i] <= a[j])
        {
            tmp[k] = a[i];
            i++, k++;
        }
        else
        {
            tmp[k] = a[j];
            j++, k++;
        }
    }
    while(i <= mid)
    {
        tmp[k] = a[i];
        i++, k++;
    }
    while(j <= high)
    {
        tmp[k] = a[j];
        j++, k++;
    }
    for(k = 0, i = low; i <= high; i++, k++)
    {
        a[i] = tmp[k];
    }
    delete[] tmp;
}

void mergesort(int a[], int low, int high)
{
    int mid;
    if(low < high)
    {
        mid = (low + high) / 2;
        mergesort(a, low, mid);
        mergesort(a, mid + 1, high);
        merge(a, low, mid, high);
    }
}

int main()
{
    int n, i = 0;
    int arr[10000];
    cin >> n;
    for(i = 0; i < n; i++)
    {
        cin >> arr[i];
    }
    mergesort(arr, 0, n - 1);
    for(i = 0; i < n; i++)
    {
        cout << arr[i] << endl;
    }
    return 0;
}

第3关:快速排序

描述
给定一个数列,用快速排序算法把它排成升序。

输入
第一行是一个整数n(n不大于10000),表示要排序的数的个数;下面一行是用空格隔开的n个整数。

输出
输出排序后的数列,每个数字占一行。

输入样例
5
3 2 1 4 5

输出样例
1
2
3
4
5

#include <iostream>
using namespace std;

//划分左右子表,i是前面的指针,j是后面的指针
int partition(int arr[], int i, int j)
{
    int x = arr[i];
    while(i < j)
    {
        while (i < j && arr[j] >= x)
        {
            j--;
        }
        if(i < j)
        {
            arr[i] = arr[j];
            i++;
        }
        while(i < j && arr[i] < x)
        {
            i++;
        }
        if(i < j)
        {
            arr[j] = arr[i];
            j--;
        }
    }
    arr[i] = x;
    return i;
}

void quicksort(int arr[], int i, int j)
{
    if(i < j)
    {
        int index = partition(arr, i , j);
        quicksort(arr, i, index - 1);
        quicksort(arr, index + 1, j);  
    }
}

int main()
{
    int n, i = 0;
    int arr[10000];
    cin >> n;
    for(i = 0; i < n; i++)
    {
        cin >> arr[i];
    }
    quicksort(arr, 0, n - 1);
    for(i = 0; i < n; i++)
    {
        cout << arr[i] << endl;
    }
    return 0;
}

第4关:走迷宫

描述
判断是否能从迷宫的入口到达出口

输入
先输入两个不超过20的正整数表示迷宫的行数m和列数n,再输入口和出口的坐标,最后分m行输入迷宫,其中1表示墙,0表示空格每个数字之间都有空格。

输出
只能向上、下、左、右四个方向走若能到达,则输出"Yes",否则输出"No",结果占一行。

输入样例
3 3
0 0
2 2
0 0 0
1 1 0
0 1 0

输出样例
Yes

#include <iostream>
using namespace std;

int H[4] = {0, 1, 0, -1};
int V[4] = {-1, 0, 1, 0};
int judge = 0;

void DFS(int in_x, int in_y, int m, int n, int out_x, int out_y, int maze[][20])
{
    //一定要加这个判断。。。不然过不了。。。我是sb
    if(judge == 1)
        return;
    if(in_x == out_x && in_y == out_y)
    {
        maze[in_x][in_y] = -1;
        judge = 1;
        return;
    }                                                                                                                     
    for(int i = 0; i < 4; i++)
    {
        if(in_x >= 0 && in_y >= 0 && in_x < m && in_y < n && maze[in_x][in_y] == 0)
        {
            maze[in_x][in_y] = -1;
            DFS(in_x + H[i], in_y + V[i], m, n, out_x, out_y, maze);
            maze[in_x][in_y] = 0;
        }
    }      
}

int main()
{
    int m, n, i, j;
    int in_x, in_y, out_x, out_y;
    int maze[20][20];

    cin >> m >> n;
    cin >> in_x >> in_y >> out_x >> out_y;
    for(i = 0; i < m; i++)
    {
        for(j = 0; j < n; j++)
            cin >> maze[i][j];
    }

    DFS(in_x, in_y, m, n, out_x, out_y, maze);
    if(judge == 1)
        cout << "Yes" << endl;
    else
        cout << "No" << endl;

    return 0;
}

第5关:穷举n位二进制数

描述
输入一个小于20的正整数n,要求按从小到大的顺序输出所有的n位二进制数,每个数占一行。

输入
输入一个小于20的正整数n。

输出
按从小到大的顺序输出所有的n位二进制数,每个数占一行。

输入样例
3

输出样例
000
001
010
011
100
101
110
111

#include <iostream>
#include <math.h>
using namespace std;

int main()
{
    int n, m, j, real = 0;
    int binary[5] = {};
    cin >> n;

    for(int i = 0; i < n; i++)
    {
        real += pow(2, i);
    }

    for(int i = 0; i <= real; i++)
    {
        m = i;
        for(j = 0; m > 0; j++)
        {
            binary[j] = m % 2;
            m /= 2;
        }
        for(int k = n - 1; k >= 0; k--)
        {
            cout << binary[k];
        }
        cout << endl;
    }
    return 0;
}

第6关:穷举所有排列

描述
输入一个小于10的正整数n,按把每个元素都交换到最前面一次的方法,输出前n个小写字母的所有排列。

输入
输入一个小于10的正整数n。

输出
按把每个元素都交换到最前面一次的方法,输出前n个小写字母的所有排列。

输入样例
3

输出样例
abc
acb
bac
bca
cba
cab

#include <iostream>
#include <vector>
using namespace std;

int n;
char a[27] = {"abcdefghijklmnopqrstuvwxyz"};
void swap(int i, int j)
{
    char ch;
    ch = a[i];
    a[i] = a[j];
    a[j] = ch;
}
void perm(int i)
{
    if(i == n)
    {
        for(int j = 0; j < n; j++)
        {
            cout << a[j];
        }
        cout << endl;
    }
    else 
    {
        for(int k = i; k < n; k++)
        {
            swap(i, k); //交换2者的值
            perm(i + 1);
            swap(i, k); //交换回来
        }
    }
}
int main()
{
    cin >> n;
    perm(0);
    return 0;
}

第7关:循环赛日程表

描述
用分治算法生成循环赛日程表(1到2的n次方个人)

输入
一个小于等于7的正整数n

输出
循环赛日程表(1到2的n次方个人)

输入样例
3

输出样例
1 2 3 4 5 6 7 8
2 1 4 3 6 5 8 7
3 4 1 2 7 8 5 6
4 3 2 1 8 7 6 5
5 6 7 8 1 2 3 4
6 5 8 7 2 1 4 3
7 8 5 6 3 4 1 2
8 7 6 5 4 3 2 1

//用分治算法生成循环赛日程表(1-2的n次方个人)

#include <iostream>
#include <math.h>
using namespace std;

void table(int n, int result[][129])
{
    int i, j, m, t, temp;
    m = 2;
    result[1][1] = 1, result[1][2] = 2;
    result[2][1] = 2, result[2][2] = 1;
    for(t = 1; t < n; t++)
    {
        temp = m;
        m *= 2;
        for(i = temp + 1; i <= m; i++)
        {
            for(j = 1; j <= temp; j++)
            {
                result[i][j] = result[i - temp][j] + temp;
            }
        }
        for(i = 1; i <= temp; i++)
        {
            for(j = temp + 1; j <= m; j++)
            {
                result[i][j] = result[i + temp][j - temp];
            }
        }
        for(i = temp + 1; i <= m; i++)
        {
            for(j = temp + 1; j <= m; j++)
            {
                result[i][j] = result[i - temp][j - temp];
            }
        }
    }
}

int main()
{
    int n, people;
    int result[129][129];
    cin >> n;
    people = pow(2, n);
    table(n, result);
    for(int i = 1; i <= people; i++)
    {
        for(int j = 1; j < people; j++)
        {
            cout << result[i][j] << " ";
        }
        cout << result[i][people] << endl;
    }
    return 0;
}

第8关:求第k小数

描述
求第k小数

输入
先输入一个小于10000的正整数n,再输入n个整数,最后输入一个小于等于n的正整数k,

输出
输出其中第k小的数。

输入样例
5
2 98 34512 8492 1000
2

输出样例
98

#include <iostream>
using namespace std;

int partition(int arr[], int i, int j)
{
    int x = arr[i];
    while(i < j)
    {
        while (i < j && arr[j] >= x)
        {
            j--;
        }
        if(i < j)
        {
            arr[i] = arr[j];
            i++;
        }
        while(i < j && arr[i] < x)
        {
            i++;
        }
        if(i < j)
        {
            arr[j] = arr[i];
            j--;
        }
    }
    arr[i] = x;
    return i;
}

void quicksort(int arr[], int i, int j)
{
    if(i < j)
    {
        int index = partition(arr, i , j);
        quicksort(arr, i, index - 1);
        quicksort(arr, index + 1, j);  
    }
}

int main()
{
    int n, k;
    int num[10000];
    cin >> n;
    for(int i = 0; i < n; i++)
    {
        cin >> num[i];
    }
    cin >> k;
    quicksort(num, 0, n - 1);
    cout << num[k - 1];
    return 0;
}
  • 16
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gravity_w

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值