12.11-12.12总结(约瑟夫问题 机器翻译 滑动窗口)

时间:2024-12-14 07:08:39

12.11 刷题

《算法竞赛》这本书看了很多了,但是题目没咋做,所以今天来刷一下题

P1996约瑟夫问题

还依稀记得大一的时候被约瑟夫支配的恐惧(哭),但是现在做就感觉很简单(虽然也敲了一会,今早感觉状态不是很好)

代码如下:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll p[105];
ll n, m;
int main()
{
    cin >> n >> m;
    ll cnt = 0, index_now = 0, sum = 0;
    while (cnt < m && sum != n)
    {
        if (!p[index_now])
        {
            cnt++;
            if (cnt == m)
            {
                p[index_now] = 1;
                cout << index_now + 1 << ' ';
                cnt = 0;
                sum++;
            }
        }
        index_now = (index_now + 1) % n;
    }
    return 0;
}

P1540 机器翻译

这题首先肯定是要用到队列的,数据量也不大,本来是想用n2的复杂度直接莽的,但是后面发现通过哈希其实是可以把时间复杂度降到On的,代码如下:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll m,n;
ll hashh[1005];
queue<ll> q;
int main()
{
    cin>>m>>n;
    ll cnt=0,ans=0;//cnt是为了记录队列有没有满,ans是记录查阅次数
    for(int i=0;i<n;i++)
    {
        ll word;
        cin>>word;
        if(hashh[word]==0)
        {
            if(cnt!=m)
            {
                cnt++;
            }
            else
            {
                ll tp=q.front();
                q.pop();
                hashh[tp]=0;
            }
            q.push(word);
            hashh[word]=1;
            ans++;
        }
    }
    cout<<ans<<endl;
    return 0;
}

P1886 滑动窗口

这题以前做过,之前肯定是看模版写的单调队列(就是检查到a[i]时,让a[i]成为队列中最大的元素,来维持队列的单调性),今天我瞄了一眼发现这题完全可以用优先队列去写,因为数据量并不是很大,只有106,所以nlogn也是可以过的。

但是单调队列的时间复杂度显然要更优越,是On,所以如果数据量有109,优先队列估计也过不了

优先队列代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll n, k;
struct node
{
    ll index;
    ll value;
};
node a[1000005];
struct compare
{
    bool operator()(const node &p1, const node &p2)
    {
        if (p1.value < p2.value)
            return true;
        if (p1.value == p2.value)
            return p1.index < p2.index;
        return false;
    }
};
struct compare2
{
    bool operator()(const node &p1, const node &p2)
    {
        if (p1.value > p2.value)
            return true;
        if (p1.value == p2.value)
            return p1.index > p2.index;
        return false;
    }
};
priority_queue<node, vector<node>, compare2> q1;
priority_queue<node, vector<node>, compare> q2;
int main()
{
    cin >> n >> k;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i].value;
        a[i].index = i;
    }
    for (int i = 1; i <= n; i++)
    {
        q1.push(a[i]);
        if (i >= k)
        {
            while (q1.top().index < i - k + 1)
                q1.pop();
            cout << q1.top().value << ' ';
        }
    }
    cout << endl;
    for (int i = 1; i <= n; i++)
    {
        q2.push(a[i]);
        if (i >= k)
        {
            while (q2.top().index < i - k + 1)
                q2.pop();
            cout << q2.top().value << ' ';
        }
    }
    return 0;
}

单调队列代码:(感觉十分简洁优雅,而且队列里面只存序号这点很高明,如果是我我就定义结构体了)

#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll n, k;
deque<ll> q;
ll a[1000005];
int main()
{
    cin >> n >> k;
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    for (int i = 1; i <= n; i++)
    {
        while (!q.empty() && q.front() < i - k + 1)
            q.pop_front();
        while (!q.empty() && a[q.back()] > a[i])
            q.pop_back();
        q.push_back(i);
        if (i >= k)
            cout << a[q.front()] << ' ';
    }
    cout << endl;
    while (!q.empty())
        q.pop_back();
    for (int i = 1; i <= n; i++)
    {
        while (!q.empty() && q.front() < i - k + 1)
            q.pop_front();
        while (!q.empty() && a[q.back()] < a[i])
            q.pop_back();
        q.push_back(i);
        if (i >= k)
            cout << a[q.front()] << ' ';
        // cout << "i" << i << endl;
        // for (auto it : q)
        //     cout << a[it] << ' ';
        // cout << endl;
    }
    return 0;
}

两日总结:
写快一点吧
这三题都是12.11号刷的 今天没抽出时间刷题
昨天去找两位姐姐吃了个饭 玩的挺开心的

然后今天跟学长也出去吃了个饭 吃了日料之后又去吃川菜 笑死我了 花了310左右
撑死了

然后就是最近想法比较多 也跟子雄说了 子雄的执行力是真的强 跟他说他真的就去立马做了

最近喜欢看《马斯克传》 写的很幽默 找到新的精神支撑了

手语社那个圈子总感觉怪怪的 是我想多了么

送给自己5个字:
偏执而疯狂

去看书了