H.ProblematicPublicKeys[欧拉素数筛][stl][vector][一维数组去重][unique函数][erase函数]

6 篇文章 0 订阅
1 篇文章 0 订阅

On February 15, 2012, the New York Times reported a flaw in the method of generating keys for a 

public-key encryption system (“Researchers Find a Flaw in a Widely Used Online Encryption Method" 

by John Markoff). This flaw enables an attacker to determine private keys given a set of flawed public 

keys.

Your job is to write a program that takes flawed public keys and determines the corresponding private 

keys. For the purposes of this problem, a private key consists of a pair of prime numbers,

2 < K1,K2 < 231

and the corresponding public key consists of the product K1  K2.

Input

The first line of the input contains an integer value, M (2  M  100). M is the number of input lines 

that follow. Each of the M lines contains a single “public key." Each public key is the product of 

exactly two prime numbers and will fit in a 32-bit unsigned integer.

Output

The output lines produced by your program should contain the unique prime factors of the input data 

values in ascending numeric order, five per line, except for the last line. Output values on the same 

line are separated by a single space.

Sample 1:

6

221

391

713

1457

901

299

 

13 17 23 31 47

53

Sample 2:

2

2143650557

2140117121

 

32717 65413 65521

欧拉素数筛:

ll prime[100010];
bool vis[100010];
void init()
{
    memset (vis,true,sizeof (vis));
        vis[1]=false;
    int cnt=0;
        for (int i=2; i<100000; i++)
        {
            if (vis[i])
                prime[cnt++]=i;
            for (int j=0; j<cnt&&i*prime[j]<100000; j++)
            {
                vis[i*prime[j]]=false;
                if (i%prime[j]==0)
                    break;
            }
        }
}

vector一维数组去重:

   vector基本用法:

vector<ll>p;
p.push_back( prime[i]);
int len=p.size();

   一维数组去重:

sort(p.begin(),p.end());
p.erase(unique(p.begin(), p.end()), p.end());

erase函数:清除容器中的元素

vector<ll>v;
v.erase(a);//a为准确的地址,删除的是a地址以后的元素
v.erase(a,b);//a,b均为地址,删除a与b之间的元素

第二个有返回值,返回位置b

进阶用法:

vector<string> e = {"a","b","c","d","e","f","g"};
auto it = a.begin();
auto it2 = find(a.begin(), a.find(), "c");        //it2指向“c”所在位置
auto it3 = a.erase(it,it2);    //删除it到it2之间的所有元素,即“a”和“b”
a.erase(it3);                  //此时删除的是“c”,即先前it2所指,因为第三种用法返回的就是第二个迭代器所指位置

string用法:

string str ("This is an example phrase.");
str.find("an");
str.erase(10);            // 也可以使用下标进行删除操作,删除下标10开始及以后的字符
str.erase (10,8);          // 此处意为删除下标‘10’开始的连续8个字符

参考:https://blog.csdn.net/Leo_csdn_/article/details/82221721?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522158780735119195239805099%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=158780735119195239805099&biz_id=0&utm_source=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v25-1

unique函数:

使用#include<algorithm>头文件

作用:去除容器或数组中相邻的重复元素

所以在使用之前要先sort()一下

!!!这里的去除并非真正意义的erase,而是将重复的元素放到容器的末尾,返回值是去重之后的尾地址。 

ac代码:

#include<iostream>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<set>
#include<numeric>
#include<vector>
#include<queue>
#include<array>
#define _USE_MATH_DEFINES
using namespace std;
typedef long long ll;
const int mod=10^9+7;
#define inf 0x3f3f3f3f
//tuple<int,int,int>p[100000]
ll prime[100010];
bool vis[100010];
void init()
{
    memset (vis,true,sizeof (vis));
        vis[1]=false;
    int cnt=0;
        for (int i=2; i<100000; i++)
        {
            if (vis[i])
                prime[cnt++]=i;
            for (int j=0; j<cnt&&i*prime[j]<100000; j++)
            {
                vis[i*prime[j]]=false;
                if (i%prime[j]==0)
                    break;
            }
        }
}
int main()
{
    init();
    int m;
    cin>>m;
    vector<ll>p;
    ll n;
    while(m--)
    {
        cin>>n;
       // priority_queue<ll,vector<ll>,greater<ll>>ans;
        int i=0;
        while(1)
        {
            if(n%prime[i]==0)
            {
                p.push_back( prime[i]);
                //cout<<" "<<prime[i]<<" ";
                p.push_back(n/prime[i]);
                //cout<<" "<<n/prime[i]<<endl;
                break;
            }
            i++;
        }
    }
    sort(p.begin(),p.end());
    p.erase(unique(p.begin(), p.end()), p.end());
    int len=p.size();
    for(int i=0;i<len;i++)
    {
        cout<<p[i];
        if((i+1)%5==0&&i!=len-1)
            cout<<endl;
        else if(i!=len-1)
            cout<<" ";
    }
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值