Backdoor CTF 2013: 杂项 75-----定时求随机个素数之和

题目

打开传送门之后,题目要求在3秒内提交前N(随机个)素数的和。

re.findall(pattern, string):详细看

搜索string,以列表形式返回全部能匹配的子串。

r(raw)用在pattern之前,表示单引号中的字符串为原生字符,不会进行任何转义

+加号,指定将前面的RE重复1次或者任意多次,而且总是试图尽量多次地匹配。

re.findall(r'[a-z]+','liuyaN1234ab9') #返回['liuya', 'ab']


本题的思路:

1.首先生成质数列表:
2.然后是读取素数表计算前N个素数的和并提交结果:

import requests
import re
import math
 
def prime_generate(n):
    result = list()
    result.append(2)
    result.append(3)
    for i in xrange(5,n+1,2):
        for j in xrange(3,int(math.sqrt(i))+1):
            if i%j == 0:
                break
        else:
            result.append(i)
    return result
 
def calc_sum(num):
    finsum=0
    for x in prime_generate(10000)[:num]:
        finsum=finsum+x
    return finsum  
 
def main():
    url = "http://hack.bckdr.in/2013-MISC-75/misc75.php"
    req = requests.get(url)
    tmpcookies = req.cookies
    # Set random N.
    match = re.findall(r'[0-9]+', req.text); num = int(match[1])
    sum=calc_sum(num)
    data = {"answer": sum}
    req2 = requests.post(url, data=data, cookies=tmpcookies)
    print(req2.text)
 
if __name__ == "__main__":
    main()


如果想更快我觉得可以用筛选法:

我做了一个比较:

1.从奇数里挑素数+直到开根号(N)

#include<iostream>  
#include<cmath>
using namespace std;    
int prime_table(int N )  {
	
	int i = 0, j = 0 , count = 0;  
    int *prime = new int[N + 1];  
    if (NULL == prime)          return -1; 
    prime[2] = 1; 
    for (i = 3; i <= N; i+=2)   
    {  
        prime[i] = 1;  
    }
    for (i = 3; i <= N; i+=2) 
    {  
        
        for (j = 3; j <= sqrt(i); j++)    
        {  
        	if (i%j == 0)
        	{
        	  prime[i] = 0; 
        	  count++;  
			  break;
        	}
        	 count++;  
           
        }  
    }  
    
     cout << "Times of calculation : " <<  count << "\n";  
    for (i = 2; i <= N; i++)   
    {  
        if (prime[i] == 1)   
        {  
            cout << "\t" << i;      
            if(j++ % 10 == 0)  
            {  
                cout << '\n';  
            }  
        }  
    }  
	delete [] prime;  
    return 0; 
	
}

int main()  
{  
    int n;  
	cin >> n;  
        prime_table(n);  
        cout << "\n";  
    return 0;  
}  


2.筛选发

#include<iostream>  
using namespace std;    
int prime_table(int N )  
{  
    int i = 0, j = 0 , count = 0;  
    int *prime = new int[N + 1];  
    if (NULL == prime)          return -1;  
  
    for (i = 2; i <= N; i++)   
    {  
        prime[i] = 1;  
    }  
  
    for (i = 2; i * i <= N; i++)   
    {  
        if (prime[i] == 0)   
        {  
            count++;  
            continue;  
        }  
        for (j = i * i; j <= N; j = j + i)   
        {  
            prime[j] = 0;  
            count++;  
        }  
    }  
    cout << "Times of calculation : " <<  count << "\n";  
    for (i = 2; i <= N; i++)   
    {  
        if (prime[i] == 1)   
        {  
            cout << "\t" << i;      
            if(j++ % 10 == 0)  
            {  
                cout << '\n';  
            }  
        }  
    }  
    delete [] prime;  
    return 0;  
}    
int main()  
{  
    int n;  
	cin >> n;  
        prime_table(n);  
        cout << "\n";  
    return 0;  
}  





参考1

参考2

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值