IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 牛客挑战赛56AB题 -> 正文阅读

[数据结构与算法]牛客挑战赛56AB题

A题:
思路:
这道题首先观察题目性质可以得到:只有当ai 和 aj存在倍数关系时才能得到 ai | aj >= lcm(ai, aj);
证明:
ai | aj <= ai + aj 因为按位或是不进位加法,所以两个数按位或一定小于等于两个数相加
若ai 和 aj 均大于 1 时,ai * aj >= ai + aj >= ai | aj;
lcm(ai,aj) >= ai * aj, 当取等于时,ai 和 aj存在倍数关系,所以只有当ai 和 aj存在倍数关系时,才可能取到ai | aj >= lcm(ai, aj);
若ai 和 aj存在一个数位1时,ai 与 aj之间肯定存在倍数关系
至此可以证明只有ai 和 aj 之间存在倍数关系时,可以得到ai | aj >= lcm(ai, aj);

#include"bits/stdc++.h"

using namespace std;

const int N = 2e5 + 10, M = 2E6 + 10;
int a[N];
bool st[M];
map<int,int>f;
int main()
{
    int n;
    cin >> n;
    int maxn = 0;
    for(int i = 0; i < n; i ++)
    {
         scanf("%d", &a[i]), maxn = max(maxn, a[i]);//输入a[i],且找到a序列中最大值
        if(st[a[i]])//判断a序列中是否存在两个a[i],若存在两个a[i],则两个a[i]之间存在倍数关系直接输出答案
        {
            cout << f[a[i]] + 1 << ' ' << i + 1 << endl;
            return 0;
        }
        f[a[i]] = i;//存储每个a[i]出现的位置
        st[a[i]] = true;//记录每个值是否出现过
    }
    
   
   sort(a , a + n);    
    for(int i = 0; i < n ;i ++)
    {
        if(a[i] * 2 > maxn)break;//因为之前判断了一倍的倍数关系,所以这里最小是两倍的倍数关系,若两倍a[i]大于序列的最大值,则直接退出循环
        int k = 2;
        while(a[i] * k <= maxn)
        {
            if(st[a[i] * k])//判断k倍a[i]是否出现过
            {
                cout << min(f[a[i]], f[a[i] * k]) + 1 << ' ' << max(f[a[i]], f[a[i] * k]) + 1;
                return 0;
            }
            ++ k;
        }
    }
    cout << -1;
}

B题:
思路:直接模拟。(每个人可以根据自己的想法来完成代码)
注意事项:
你所构造的m中排序中,必须满足每个人在这m种排序中的位置的最小值等于题目所给定的最小值
也就是说你构造的序列
a11…a1n
a21…a2n

am1…amn
任意的第i列的最小值必须等于x[i] (1 <= i <= n)
x[i]为题目所给定的每个人的位置

#include"bits/stdc++.h"

using namespace std;
const int N = 2010;
vector<int>f[N];//存储题目给定的每个要求
vector<int>res[N];//存储m中排序的答案
vector<int>ans[N];//存储每个人在m中排序中的答案
set<int>s[N];//存储每个人在m中排序中是否已经出现
int n , m, x[N], mini[N];
void solve(int nn,int k)
{
    if(nn == 0)return ;//若n个条件全部处理完则直接退出递归
    nn -= f[k].size();//减去本轮处理的条件
    
    if(f[k].size() > m)
    {
        cout << "No";//若当前想要排名位第k位的人大于m,则直接输出答案退出程序
        exit(0);
    }
    for(int i = 0; i < f[k].size(); i ++)
        res[i].push_back(f[k][i]), s[i].insert(f[k][i]);//把每个想要排名位K的人安排进m个排序中
    
    int t = f[k].size();
    while(t < m)//若想要排名位k的人小于m,则拿想要排名<=k的人来填补剩下没有填满的位置
    {
        bool flag = false;
        for(int i = 0; i <= k ;i ++)
        {
            for(int j = 0; j < f[i].size(); j ++)
            {
                if(!s[t].count(f[i][j]))
                {
                    res[t].push_back(f[i][j]);
                    s[t].insert(f[i][j]);
                    flag = true;
                    break;
                }
            }
            if(flag)break;
        }
        if(!flag)
        {
            cout << "No";//若找不到人填补位置则直接输出答案退出
            exit(0);
        }
        t ++;
    }
    solve(nn, k + 1);
}

int main()
{
    cin >> n >> m;
    for(int i = 1; i <= n ;i ++)
    {
        s[i].clear();
        cin >> x[i];
        f[x[i]].push_back(i);//把每个人的要求存储到相应的vector中
    }
        solve(n, 1);//递归处理题目给定的n个条件
    
    for(int i = 0 ;i < m ;i ++)
    {
        if(res[i].size() < n)
        {
            for(int j = 1; j <= n ;j ++)
                if(!s[i].count(j))
                    res[i].push_back(j);
        }
    }
    memset(mini, 0x3f, sizeof mini);
    for(int i = 0 ;i < m ;i ++)//把题目没有限定的位置填补满
    {
        for(int j = 0; j < n ;j ++)
        {
            ans[res[i][j]].push_back(j + 1);
            mini[res[i][j]] = min(mini[res[i][j]], j + 1);
        }
    }
    for(int i = 1; i <= n ;i ++)
        if(mini[i] != x[i])//若i这个人在我们安排的位置中的最小值小于了题目给定的最小值,则无解
        {
            cout << "No";
            return 0;
        }
    cout << "Yes" << endl;//输出答案
    for(int i = 1; i <= n ;i ++)
    {
        for(int j = 0 ;j < m ;j ++)
            if(j == 0)printf("%d", ans[i][j]);
            else printf(" %d", ans[i][j]);
        cout << endl;
    }
}```

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-01-08 14:16:53  更:2022-01-08 14:17:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 18:36:58-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码