参考大佬的博客
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;