POJ2635 The Embarrassed Cryptographer 简单数论

题目链接

看到这题的示意图也是醉了~题意:给你一个k,他是两个素数之积,然后给了一个数字L,然后找到具体是哪两个素数相乘等于k,较小的那个素数是否小于L,若小于L就输出 "BAD"外加较小的那个素数,否则就输出“GOOD”,

刚拿到这题目,有些钻牛角尖外加题意没看清楚,一开始纠结于 K很大,若想具体找出两个素数不可能,因为总有一个很大很大,求出其中一个素数 是否在10^6内是可以的,但是那时候我觉得还需要证明 k/prime  的值必须也是素数才符合要求,其实题目都规定好了 k必定是两个素数之积 而不会由其它合数相乘构成,所以就简单了许多

我不知道这个是什么定理的,但是对于一个很长的数字 比如  123456789,若把它每位上数字存在数组num中,123456789%m也等于

int now = 0;

for(int i=0;i<9;i++) now = (now * 10 + num[i])%m;

如果知道这个的话就好做了,对于K其实可以转化为大进制的数字存在数组里,比如转化为千进制万进制,先保存好,最后 计算的时候再乘以一千或者一万,上面那个for是相对于十进制的,把那个now*10改成对应进制即可,剩下的枚举素数只需要打印素数表即可,一开始害怕K太大存不下来而没有去细算直接转化为万进制,结果一直WA,后来转化为千进制就过了,原因是 for循环时每次取余的时候,余数最大可达10^6,然后再乘10000就会爆int,然后又改成了 long long,转化为万进制,也是可以过的

string s;

int L;

int nnum[100000 + 5];

int cnt ;

bool isprime[1000000 + 55];
int prime[1000000 + 55];
int k;

void make_prime() {
	memset(isprime,false,sizeof(isprime));
	for(int i=2;i<1000055 ;i++)
		if(!isprime[i])
			for(int j=i*2;j<1000055;j+=i)
				isprime[j]=true;
	for(int i=2;i<1000055;i++)
		if(!isprime[i])
			prime[k++]=i;
}

void init() {
	memset(nnum,0,sizeof(nnum));
	cnt = 0;
}

bool input() {
	while(cin>>s>>L) {
		if(s == "0" && L == 0)break;
		return false;
	}
	return true;
}

void slove() {
	int len = s.length();
	for(int i=len - 1;i >= 0;i-=3) {
		for(int j= i - 2;j<=i;j++) {
			if(j < 0)j = 0;
			nnum[cnt] = nnum[cnt] * 10 + s[j] - '0';
		}
		cnt++;
	}
}

bool gao(int x) {
	int ret = 0;
	for(int i= cnt - 1;i>=0;i--) {
		ret = (ret * 1000 + nnum[i])%x;
	}
	if(ret)return false;
	return true;
}

void cal() {
	slove();
	for(int i=0;i<k && prime[i] < L;i++) {
		if(gao(prime[i])) {
			printf("BAD %d\n",prime[i]);
			return ;
		}
	}
	puts("GOOD");
}

void output() {

}

int main() {
	make_prime();
	while(true) {
		init();
		if(input())return 0;
		cal();
		output();
	}
	return 0;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值