UVA - 12253 Simple Encryption (同余)

Some day in the future a personnamed Reuben wants to submit some interesting problems to the judging directorof ACM ICPC (Association for Copotron Mechanics International CollegiateProgramming Contest) World Finals so that they can be used in World Finals2031. This contest requires problem submitters to submit their problems inencrypted format. But in year 2030, encryption software is notwidely available on the Internet just to prevent terrorists from sendingencrypted messages. So he wants to use a simplified encryption technique tosubmit his problem. He uses several 12-digit encryption keys to encrypt hismessages. We would not disclose the encryption/decryption technique for safetybecause your next generations will be competing in World Finals by then. ButReuben also does not want to send his encryption key in a straightforwardemail. He wants to send a key (public) K1 that will implicitlydenote the actual key (private) K2. K2 issuch a 12 digit number so that  (modulo 1012).Given the value of K1 your job is to help Reuben find thevalue of K2.

 

Input

The input file contains around 1600line of input. Each line contains an integer, which denotes the value of K1(0<K1<50001). A line containing a single zero terminatesinput.

 

Output

For eachline of input produce one line of output. This line contains the serial ofoutput, followed by the given public key K1andthen a possible actual private key K2. Look at the output forsample input for exact formatting. Inputs will be such that for given value of K1there will always be at least one value of K2.Note that K2 should always have 12 digits and will nothave any leading zeroes.

 

SampleInput       Output for Sample Input

78

99

0

Case 1: Public Key = 78 Private Key = 308646916096

Case 2: Public Key = 99 Private Key = 817245479899

 


Problemsetter: ShahriarManzoor, Special Thanks: Derek Kisman

题意:输入正整数K1,找一个12位正整数K2,是的k1^k2%10^12 = K2%10^12。

思路:枚举每一位,通过同余判断DFS的过程

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
typedef long long ll;
using namespace std;
const ll bit = (1ll<<20) - 1;
const ll inf = 1000000000000ll;

ll ans;
int n, k;

ll mul(ll a, ll b, ll m) {
	return (a*(b>>20)%m*(1ll<<20)%m+a*(b&(bit))%m)%m;
}

ll pow_mod(ll a, ll b, ll m) {
	ll ans = 1;
	while (b) {
		if (b & 1)
			ans = mul(ans, a, m);
		b >>= 1;
		a = mul(a, a, m);
	}
	return ans;
}

int dfs(int deep, ll now, ll m) {
	if (deep == 12) {
		if (pow_mod(k, now, inf) == now && now >= inf/10) {
			ans = now;
			return 1;
		}
		return 0;
	}

	for (int i = 0; i <= 9; i++) 
		if (pow_mod(k, i*m + now, m) == now) 
			if (dfs(deep+1, i*m+now, m*10))
				return 1;
	return 0;
}

int main() {
	int cas = 1;
	while (scanf("%d", &n) != EOF && n) {
		k = n;
		printf("Case %d: ", cas++);	
		for (int i = 0; i <= 9; i++) 
			if (dfs(1, i, 10)) {
				printf("Public Key = %d Private Key = %lld\n", k, ans);
				break;
			}
	}
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值