2022-03-22每日刷题打卡

2022-03-22每日刷题打卡

力扣春季赛开始啦,佬们求求给战队点个赞吧(每天都可以点的):啊哈哈哈AC来咯

代码源——每日一题

可重排列 - 题目 - Daimayuan Online Judge

按字典序从小到大,输出所有序列,满足其中有p1个1, p2个2, ……, pn个n。

输入格式

第一行,一个整数n。

第二行,若干个整数p1,p2,…,pn。

输出格式

若干行,每行若干个整数,表示满足条件的序列。

样例输入
3
1 2 2
样例输出
1 2 2 3 3
1 2 3 2 3
1 2 3 3 2
1 3 2 2 3
1 3 2 3 2
1 3 3 2 2
2 1 2 3 3
2 1 3 2 3
2 1 3 3 2
2 2 1 3 3
2 2 3 1 3
2 2 3 3 1
2 3 1 2 3
2 3 1 3 2
2 3 2 1 3
2 3 2 3 1
2 3 3 1 2
2 3 3 2 1
3 1 2 2 3
3 1 2 3 2
3 1 3 2 2
3 2 1 2 3
3 2 1 3 2
3 2 2 1 3
3 2 2 3 1
3 2 3 1 2
3 2 3 2 1
3 3 1 2 2
3 3 2 1 2
3 3 2 2 1
数据规模

对于100%的数据,保证1≤n≤9,1≤pi≤9,保证总的序列个数不超过10^5个。

两个做法:

1、用dfs枚举每个位置上可能的数字,枚举完最后一位的时候把整个数组输出。

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")

#define endl '\n';
typedef long long ll;
typedef pair<ll, ll>PII;
const int N = 1e6 + 50;
int f[N], n, u;
vector<int> v;

void dfs()
{
    if (v.size() == u)
    {
        for (auto i : v)cout << i << " ";
        cout << endl;
        return;
    }
    for (int i = 1; i <= n; i++)
    {
        if (f[i] != 0)
        {
            f[i]--;
            v.push_back(i);
            dfs();
            v.pop_back();
            f[i]++;
        }
    }
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> f[i];
        u += f[i];
    }
    dfs();
    return 0;
}

2、next_permutation

next_permutation() 会生成一个序列的重排列,它是所有可能的字典序中的下一个排列,默认使用 < 运算符来做这些事情。它的参数为定义序列的迭代器和一个返回布尔值的函数,这个函数在下一个排列大于上一个排列时返回 true,如果上一个排列是序列中最大的,它返回 false,所以会生成字典序最小的排列。

使用样例:(生成1~4的所有可能排列)

 vector<int> range{ 1,2,3,4 };
    do {
        copy(begin(range), end(range), ostream_iterator<int>{cout, " "});
        cout << endl;
    } while (next_permutation(std::begin(range), end(range)));

结果:

1 2 3 4
1 2 4 3
1 3 2 4
1 3 4 2
1 4 2 3
1 4 3 2
2 1 3 4
2 1 4 3
2 3 1 4
2 3 4 1
2 4 1 3
2 4 3 1
3 1 2 4
3 1 4 2
3 2 1 4
3 2 4 1
3 4 1 2
3 4 2 1
4 1 2 3
4 1 3 2
4 2 1 3
4 2 3 1
4 3 1 2
4 3 2 1

只要一开始给出这组序列的最小字典序的序列,我们就可以很方便的得到一串数的全排列结果

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")

#define endl '\n';
typedef long long ll;
typedef pair<ll, ll>PII;
const int N = 1e6 + 50;

int f[10],len,mymap[N];

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int n,x=1;
    cin >> n;
    vector<int>ans;
    for (int i = 1; i <= n; i++)
    {
        cin >> f[i];
        for (int j = 0; j < f[i]; j++)
        {
            ans.push_back(x);
        }
        x++;
    }
    do {
        copy(begin(ans), end(ans), ostream_iterator<int>{cout, " "});
        cout << endl;
    } while (next_permutation(begin(ans), end(ans)));
    return 0;
}
字典序最小 - 题目 - Daimayuan Online Judge

从序列 MM 个数中顺序选出 NN 个不同的数, 使得这 NN 个数的字典序最小。

输入格式

第一行两个整数 M, N分别表示序列长度,顺序选取数据的个数 (其中1<N≤M≤10^6)。

接下来 M 行,第 i 行输入为第 ai,表示序列 M 中第i 个数,其中 1≤ai≤N, 数据保证 [1,N] 范围内每个数至少出现一次。

输出格式

输出 N 个数, 用空格隔开, 表示最小字典序 (最后一个输出不能有多余空格)。

样例输入
6 3
3
2
1
3
1
3
样例输出
2 1 3
题目说明

求解的最小字典序不必在序列 M 中连续。

这题我们想要得到最小的字典序,那前面的数都要尽可能小,随着遍历数组我们要更新更小的元素,同时把大的元素从记录的序列中移除,这一性质就很适合我们单调栈。

我们先预处理一下,用一个数组f先记录每个数的出现次数,然后用一个栈遍历数组,每遍历到一个数,数组f里这个数的出现次数–,如果栈为空,就把遍历到的元素入栈,并且用一个数组记录当前栈内的元素;如果栈不为空,而且当前元素没有在栈内,就用当前元素和栈顶元素比较一下,如果栈顶元素在数组的出现次数不为0(数组后面还会出现),就把这个元素出栈,然后继续用当前元素和新的栈顶元素对比,直到新的栈顶元素在数组后面不再出现(如果此时再删,那这个数就永远丢失了),或者栈顶元素小于当前元素是停止出栈,把元素入栈。如果一开始当前元素已经在栈内了,那就不用进行出栈操作(我们出栈是为了把小的数尽可能放前面,既然这个元素已经有在栈内了就不用在出栈了),最后把栈内元素反向输出就行。

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")

#define endl '\n';
typedef long long ll;
typedef pair<ll, ll>PII;
const int N = 1e6 + 50;

int f[N];

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int n,m;
    cin >> n >> m;
    vector<int>v(n),mymap(N+1);
    for (int i = 0; i < n; i++)
    {
        cin >> v[i];
        f[v[i]]++;
    }
    stack<int>sta;
    sta.push(v[0]);
    f[v[0]]--;
    mymap[v[0]] = 1;
    for (int i = 1; i < n; i++)
    {
        while (!sta.empty() && sta.top() > v[i] && f[sta.top()] > 0 && mymap[v[i]] != 1)
        {
            mymap[sta.top()] = 0;
            sta.pop();
            
        }
        if (mymap[v[i]] == 0)
        {
            sta.push(v[i]);
            mymap[v[i]] = 1;
        }
        f[v[i]]--;
    }
    vector<int>res;
    while (!sta.empty())
    {
        res.push_back(sta.top());
        sta.pop();
    }
    cout << res[m - 1];
    for (int i = m - 2; i >= 0; i--)cout << " " << res[i] ;
    return 0;
}
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值