hdu 2462 poj 3696 The Luckiest number fzu 1017 zoj 1537 Playing with Calculator

题目思路:
求解10^x = 1 (mod 9*L/gcd(L,8))的满足x>0的最小解就是答案
由8构成的数A设有x位
那么A=8(10^0+10^1+...+10^(x-1));
很容易得到A=(8/9)*(10^x-1);
题目的要求就是A=0(mod L)
就是(8/9)*(10^x-1)=0(mod L);
->8*(10^x-1)=0(mod 9L);
->10^x-1=0(mod 9L/gcd(L,8));
->10^x =1 (mod 9L/gcd(L,8));
令p=9*L/gcd(L,i), 等价于10^x==1(mod p),求满足条件的最小的整数x
看到这个式子,我们的第一反应就是数论书上的Euler定理,但是如果gcd(10,p)!=1,即不互素,也就是不满足欧拉定理的条件了,所以此时为no answer.
if(gcd(10,p)==1) 满足欧拉定理, 我们知道10^oula(p)==1(mod p)肯定是满足的;
虽然oula(p)满足上述同余方程,但题目求是最小x,而oula(p)未必是最小的解。考虑到oula(p)不是素数,所以我们就要将oula(p)因子分解,求出oula(p)所有的因子,然后逐个从小到大枚举,如果满足10^x==1(mod p) (其中x为oula(p)的因子),x即为答案。
 
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#define LL long long
#define nmax 134165
#define nnum 13000
#define num8 8
#define num9 9
#define num10 10
int flag[nmax], prime[nnum], cpfactor[nnum];
LL pfactor[nnum], factor[nnum];
int plen, len_pfactor, len_factor;
void mkprime() {
int i, j;
memset(flag, -1, sizeof(flag));
for (i = 2, plen = 0; i < nmax; i++) {
if (flag[i]) {
prime[plen++] = i;
}
for (j = 0; (j < plen) && (i * prime[j] < nmax); j++) {
flag[i * prime[j]] = 0;
if (i % prime[j] == 0) {
break;
}
}
}
}
int cmp(const void *a, const void *b) {
LL temp = *(LL *) a - *(LL *) b;
if (temp > 0) {
return 1;
} else if (temp < 0) {
return -1;
}
return 0;
}
LL getPhi(LL n) {
int i, te;
LL phi;
te = (int) sqrt(n * 1.0);
for (i = 0, phi = n; (i < plen) && (prime[i] <= te); i++) {
if (n % prime[i] == 0) {
phi = phi / prime[i] * (prime[i] - 1);
while (n % prime[i] == 0) {
n /= prime[i];
}
}
}
if (n > 1) {
phi = phi / n * (n - 1);
}
return phi;
}
LL modular_multi(LL a, LL b, LL c) {
LL res, temp;
res = 0, temp = a % c;
while (b) {
if (b & 1) {
res += temp;
if (res >= c) {
res -= c;
}
}
temp <<= 1;
if (temp >= c) {
temp -= c;
}
b >>= 1;
}
return res;
}

LL modular_exp(LL a, LL b, LL c) {
LL res, temp;
res = 1 % c, temp = a % c;
while (b) {
if (b & 1) {
res = modular_multi(res, temp, c);
}
temp = modular_multi(temp, temp, c);
b >>= 1;
}
return res;
}
LL gcd(LL a, LL b) {
if (a < b) {
a ^= b, b ^= a, a ^= b;
}
if (b == 0) {
return a;
}
if (!(a & 1) && !(b & 1))
return gcd(a >> 1, b >> 1) << 1;
else if (!(b & 1))
return gcd(a, b >> 1);
else if (!(a & 1))
return gcd(a >> 1, b);
else
return gcd(b, a - b);
}
void findpFactor(LL n) {
int i, te, cnt;
te = (int) sqrt(n * 1.0);
for (i = 0, len_pfactor = 0; (i < plen) && (prime[i] <= te); i++) {
if (n % prime[i] == 0) {
cnt = 0;
while (n % prime[i] == 0) {
cnt++;
n /= prime[i];
}
pfactor[len_pfactor] = prime[i];
cpfactor[len_pfactor++] = cnt;
}
}
if (n > 1) {
pfactor[len_pfactor] = n;
cpfactor[len_pfactor++] = 1;
}
}
void dfs(int k, LL now) {
if (k == len_pfactor) {
factor[len_factor++] = now;
return;
}
int i;
for (i = 0; i < cpfactor[k]; i++) {
now = now * pfactor[k];
dfs(k + 1, now);
}
for (i = 0; i < cpfactor[k]; i++) {
now = now / pfactor[k];
}
dfs(k + 1, now);
}

void solve(int n) {
int i, d;
LL c, phi;
d = gcd(n, num8);
c = (LL) n;
c = c / d * num9;
if (gcd(num10, c) != 1) {
puts("0");
return;
}
phi = getPhi(c);
findpFactor(phi);
len_factor = 0;
dfs(0, 1);
qsort(factor, len_factor, sizeof(factor[0]), cmp);
for (i = 0; i < len_factor; i++) {
if (modular_exp(num10, factor[i], c) == 1) {
printf("%I64d\n", factor[i]);
return;
}
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
#endif
int n, cas;
mkprime();
cas = 0;
while (~scanf("%d", &n), n) {
printf("Case %d: ", ++cas);
solve(n);
}
return 0;
}

另一种思路:
 
/*
* hdu2462.c
*
* Created on: 2011-9-9
* Author: bjfuwangzhu
*/

#include
<stdio.h>
#include
<string.h>
#include
<math.h>
#include
<stdlib.h>
#define LL long long
#define nmax 134165
#define nnum 12510
int flag[nmax], prime[nnum];
LL factor[nnum], cfactor[nnum], num[nnum];
int plen, nlen, flen;
void init() {
memset(flag,
-1, sizeof(flag));
int i, j;
for (i = 2, plen = 0; i < nmax; i++) {
if (flag[i]) {
prime[plen
++] = i;
}
for (j = 0; (j < plen) && (i * prime[j] < nmax); j++) {
flag[i
* prime[j]] = 0;
if (i % prime[j] == 0) {
break;
}
}
}
}
LL gcd(LL a, LL b) {
if (a < b) {
a
^= b, b ^= a, a ^= b;
}
if (b == 0) {
return a;
}
if ((!(a & 1)) && (!(b & 1))) {
return gcd(a >> 1, b >> 1) << 1;
}
if (!(a & 1)) {
return gcd(a >> 1, b);
}
if (!(b & 1)) {
return gcd(a, b >> 1);
}
return gcd(a - b, b);

}
LL phi(LL n) {
int temp, i;
LL pphi;
temp
= (int) (sqrt(n * 1.0));
for (i = 0, pphi = n; (i < plen) && (prime[i] <= temp); i++) {
if (n % prime[i] == 0) {
pphi
= pphi / prime[i] * (prime[i] - 1);
while (n % prime[i] == 0) {
n
/= prime[i];
}
}
}
if (n > 1) {
pphi
= pphi / n * (n - 1);
}
return pphi;
}
LL modular_mul(LL a, LL b, LL c) {
LL res;
res
= 0, a %= c;
while (b) {
if (b & 1) {
res
+= a;
if (res >= c) {
res
-= c;
}
}
a
<<= 1;
if (a >= c) {
a
-= c;
}
b
>>= 1;
}
return res;
}
LL modular_exp(LL a, LL b, LL c) {
LL res;
res
= 1 % c, a %= c;
while (b) {
if (b & 1) {
res
= modular_mul(res, a, c);
}
a
= modular_mul(a, a, c);
b
>>= 1;
}
return res;
}
void findFactor(LL n) {
int i, te, cnt;
te
= (int) (sqrt(n * 1.0));
for (i = 0, flen = 0; (i < plen) && (prime[i] <= te); i++) {
if (n % prime[i] == 0) {
cnt
= 0;
while (n % prime[i] == 0) {
cnt
++;
n
/= prime[i];
}
cfactor[flen]
= cnt;
factor[flen
++] = prime[i];
}
}
if (n > 1) {
cfactor[flen]
= 1;
factor[flen
++] = n;
}
}
void bfs(int k, LL now, LL n) {
if (k == flen) {
num[nlen
++] = now;
return;
}
int i;
for (i = 0; i < cfactor[k]; i++) {
now
*= factor[k];
bfs(k
+ 1, now, n);
}
for (i = 0; i < cfactor[k]; i++) {
now
/= factor[k];
}
bfs(k
+ 1, now, n);
}
int cmp(const void *a, const void *b) {
LL n
= *(LL *) a;
LL m
= *(LL *) b;
LL temp;
temp
= n - m;
if (temp > 0) {
return 1;
}
if (temp < 0) {
return -1;
}
return 0;
}
void solve(LL n) {
LL nphi;
nphi
= phi(n);
findFactor(nphi);
nlen
= 0;
bfs(
0, 1, nphi);
qsort(num, nlen,
sizeof(num[0]), cmp);
int i;
for (i = 0; i < nlen; i++) {
if (modular_exp(10, num[i], n) == 1) {
printf(
"%I64d\n", num[i]);
return;
}
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen(
"data.in", "r", stdin);
#endif
init();
int cas;
LL n;
cas
= 0;
while (scanf("%I64d", &n) != EOF,n) {
cas
++;
if (n == 1) {
printf(
"Case %d: 1\n", cas);
continue;
}
if (n % 16 == 0 || n % 5 == 0) {
printf(
"Case %d: 0\n", cas);
continue;
}
n
= n / gcd(n, 8) * 9;
printf(
"Case %d: ", cas);
solve(n);
}
return 0;
}

 

 

/*
* fzu1017.c
*
* Created on: 2011-9-9
* Author: bjfuwangzhu
*/

#include
<stdio.h>
#define nnum 10
void solve(int k) {
int i, j, res;
for (i = 1; i < nnum; i++) {
for (j = 1, res = 0; j <= k; j++) {
res
= (res * 10 + i) % k;
if (res == 0) {
printf(
"%d %d\n", i, j);
return;
}
}
}
puts(
"-1");
}
int main() {
#ifndef ONLINE_JUDGE
freopen(
"data.in", "r", stdin);
#endif
int k;
while (scanf("%d", &k) != EOF) {
solve(k);
}
return 0;
}

 

转载于:https://www.cnblogs.com/xiaoxian1369/archive/2011/09/09/2172794.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值