Gym - 101911DMasquerade strikes back【从数的上一个因子开始查找】

参考大佬的博客
https://blog.csdn.net/weixin_38168173/article/details/101485441?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522160150921419725271700412%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=160150921419725271700412&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-2-101485441.first_rank_ecpm_v3_pc_rank_v2&utm_term=Gym±+101911D&spm=1018.2118.3001.4187

题目

传送门
在这里插入图片描述

输入
4
1 3 3 7
输出
YES
1 1
1 3
3 1
1 7
输入
5
3 1 3 3 7
输出
NO
输入
6
9 10 9 10 9 10
输出
YES
1 9
1 10
3 3
5 2
9 1
2 5

题意:给出一个数字n,下面是n个数字,对于每个数字输出一对因子满足a*b=x,如果能可以输出n个数的因子,输出YES,下面输出因子;否则输出NO.

思路:对于每个数字,我们都从他的上一个因子开始查找就可以了

AC code

#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<cmath>
#include<queue>
#include<stack>
using namespace std;
#define ll long long
int vis[12000000],num[12000000],a[200010];//vis反向标记,num【i】存小于sqrt(i)的因子
pair<int,int>p[200010];//a,b;
int n;
int solve()
{
    for(int i=0;i<n;i++)
    {
        if(vis[a[i]]==1)//上次找到了因子这次反向输出
    {
        vis[a[i]]=0;
        p[i].first=a[i]/num[a[i]];
        p[i].second=num[a[i]];
        continue;
    }
    else
    {
        int flag=0;
        for(int j=num[a[i]]+1;j<=sqrt(a[i]);j++)//从上一个因子的下一个数开始寻找
        {
            if(a[i]%j==0)
            {
                flag=1;
                num[a[i]]=j;
                p[i].first=j;
                p[i].second=a[i]/j;
                if(p[i].first!=p[i].second)
                   vis[a[i]]=1;
                   break;
            }


        }
        if(flag==0)return 0;
    }

    }
    return 1;
}
int main()
{
ios::sync_with_stdio;
cin>>n;
memset(vis,0,sizeof(vis));
memset(num,0,sizeof(num));
for(int i=0;i<n;i++)
   cin>>a[i];
   if(solve())
   {
       printf("YES\n");
       for(int i=0;i<n;i++)
        printf("%d %d\n",p[i].first,p[i].second);
   }
       else printf("NO\n");
}

从这个题我们也可以学到成对数字的使用pair<int,int>p[200010];
p[i].first,p[i].second;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值