データ構造第 15 週: (k 番目に大きい数値を見つける + 3 つの配列の最小の共通要素を見つける + 循環シーケンス配列の最小の要素を見つける + Crazy Search)

k 番目に大きい数を見つける

【問題内容】 n 個の数値のうち、k 番目に大きい数値を求めます。
【入力形式】 1 行目は nk、2 行目はスペースで区切られた n 個の数値です。 【
出力形式】 k 番目に大きい数値
【入力例】
10 3
18 21 11 26 12 2 9 33 43 28

【出力例】

28

[採点基準] 時間計算量が O(k n) 以上のメソッドは1/2 スコアを獲得し、時間計算量が O(n log2k) 以下のメソッドはフル スコアを獲得します。

【ヒント】

  1. さまざまな並べ替えまたは検索アルゴリズムの長所と短所を分析し、特定の問題を解決する時間の計算量を分析して、より効率的なアルゴリズムを見つけます。

  2. n と k の値は異なり、異なるアルゴリズムの効率にも影響します。たとえば、n=10、k=9 の場合、2 番目に小さい数値を見つけることができます。

#include<iostream>
using namespace std;

int QSort(int a[], int left, int right, int rk)
{
    
    
    int low = left;
    int high = right;
    int flag = a[low];
    while(low < high)
    {
    
    
        while(a[high] <= flag && low < high)
        {
    
    
            high --;
        }
        a[low] = a[high];
        while(a[low] >= flag && low < high)
        {
    
    
            low ++;
        }
        a[high] = a[low];
    }
    a[low] = flag;
    if(low == rk - 1)
        return a[low];
    else if(low > rk - 1)
        return QSort(a, left, low - 1, rk);
    else
        return QSort(a, low + 1, right, rk - low);
}
int main()
{
    
    
    int n, k;
    cin>>n>>k;
    int i = n;
    int j = -1;
    int a[n];
    while(i --)
    {
    
    
        cin>>a[++ j];
    }
    cout<<QSort(a, 0, n - 1, k);
}

3 つの配列の最小の共通要素を見つける

【問題内容】 3 つの配列の最小共通要素を求める
【入力形式】 3 つの配列、入力はすべて 0 で終わる
【出力形式】 最小共通要素
【入力例】

1 3 5 7 8 9 0

2 4 6 8 10 12 14 16 18 0

-1 3 8 16 18 19 20 168 198 0
【出力例】

8

#include<iostream>
using namespace std;
int a[1000], b[1000], c[1000];
int main()
{
    
    
    int i = 0;
    int num = 0;
    for(i = 0; ; i ++)
    {
    
    
        cin>>num;
        if(num == 0) break;
        a[i] = num; //i取到数组最后一个下标
    }
    int alen = i;
    for(i = 0; ; i ++)
    {
    
    
        cin>>num;
        if(num == 0) break;
        b[i] = num; //i取到数组最后一个下标
    }
    int blen = i;
    for(i = 0; ; i ++)
    {
    
    
        cin>>num;
        if(num == 0) break;
        c[i] = num; //i取到数组最后一个下标
    }
    int clen = i;
    int pa = 0, pb = 0, pc = 0;
    while(pa <= alen && pb <= blen && pc <= clen)
    {
    
    
        if(a[pa] == b[pb] && b[pb] == c[pc])
        {
    
    
            cout<<a[pa];
            break;
        }
        while(a[pa] < b[pb] && pa <= alen)
        {
    
    
            pa ++;
        }
        while(b[pb] < a[pa] && pb <= blen)
        {
    
    
            pb ++;
        }
        while(c[pc] < b[pb] && pc <= clen)
        {
    
    
            pc ++;
        }
    }
    return 0;
}

循環順次配列の最小要素を見つける

【問題の説明】 ループ状に並べられた連続データの集合を1次元配列に格納し、最小の要素を見つけて出力します。
【入力形式】 0で終わるデータの集合
【出力形式】 最小要素
【入力例】 7 9 11 1 3 5 0
【出力例】 1

#include<iostream>
#define N 100
using namespace std;

int FindMin(int a[], int low, int high)
{
    
    
    int mid = (low + high) / 2;
    if(a[low] < a[high])
        return a[low];
    else
    {
    
    
        if(a[low] < a[mid])
        {
    
    
            return FindMin(a, mid + 1, high);
        }
        else if(a[low] == a[mid]) return a[low];
        else
        {
    
    
            return FindMin(a, low + 1, mid);
        }
    }
}
int main()
{
    
    
    int a[N];
    int i = 0;
    int num = 0;
    for(i = 0; ;i ++)
    {
    
    
        cin>>num;
        if(num == 0) break;
        a[i] = num;
    }
    cout<<FindMin(a, 0, i - 1); //i取不到
    return 0;
}

クレイジーサーチ

[タイトル出典] 1200 – Crazy Search (poj.org) このリンクにアクセスして検出コードを送信してください

説明

多くの人は、狂気につながるような難しいパズルを解くことを好みます。そのようなパズルの 1 つは、特定のテキスト内に隠された素数を見つけることです。このような数は、テキスト内に存在する特定のサイズの異なる部分文字列の数である可能性があります。すぐにわかるように、このようなパズルを解くにはコンピューターと優れたアルゴリズムの助けが本当に必要です。
あなたのタスクは、部分文字列のサイズ N、テキスト内に出現する可能性のある異なる文字の数 NC、およびテキスト自体を指定して、テキスト内に出現するサイズ N の異なる部分文字列の数を決定するプログラムを作成することです。文章。

例として、N=3、NC=4、およびテキスト「daababac」について考えてみましょう。このテキストで見つかるサイズ 3 のさまざまな部分文字列は次のとおりです。「aab」; 「アバ」。「バブ」; 「バック」。したがって、答えは 5 になるはずです。

入力

入力の最初の行は、ちょうど 1 つのスペースで区切られた 2 つの数値 N と NC で構成されます。この後に、検索が行われるテキストが続きます。可能な文字セットによって形成される部分文字列の最大数は 1,600 万を超えないと想定できます。

出力

プログラムは、指定されたテキスト内で見つかったサイズ N の異なる部分文字列の数に対応する整数だけを出力する必要があります。

サンプル入力

3 4
daababac
サンプル出力

5

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

const int N = 1600000; // 定义16000000为什么不能运行

int main()
{
    
    
    int res = 0;
    string s;
    int sonlen;
    int sysnum; //字符串中可能出现的字符种类数
    cin>>sonlen;
    cin>>sysnum;
    cin>>s;
    int slen = s.length(); //调用string类的类函数
    int i = 0;
    bool Hash[N];
    memset(Hash, 0, sizeof(Hash));
    for(i = 0; i <= slen - sonlen; i ++)
    {
    
    
        string temp = s.substr(i,3); //截取字符串片段
        int pos = 0;
        int j = 0;
        for(j = 0; j < sonlen; j ++)
        {
    
    
            int k = 1;
            int t = int(temp[j]);
            for(k = j + 1; k <= sysnum; k ++)
            {
    
    
                t *= sysnum;
            }
            pos += t;
        }
        if(!Hash[pos])
        {
    
    
            Hash[pos] = 1;
            res ++;
        }
    }
    cout<<res;
    return 0;
}

おすすめ

転載: blog.csdn.net/qq_51800570/article/details/129186053