思路:求出n的所有因数
然后设m=n^p[i],p[i]是n的因子,就会得到原来的数,反异或即可。
AC代码:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
long long p[10000];
long long mid[10000];
long long k;
int cnt2;
int cnt;
long long gcd(long long x, long long y)
{
return y ? gcd(y, x%y) : x;
}
int main()
{
long long n;
int icase = 1;
while (~scanf("%lld",&n))
{
cnt2 = 0;
k = n;
cnt = 0;
for (long long i = 1; i*i <= n; i++)
{
if (n%i == 0)
{
p[cnt++] = i;
if (n / i != i)
p[cnt++] = n / i;
}
}
sort(p, p + cnt);
for (int i = cnt - 1; i >= 0; i--)
{
long long l = (k^p[i]);
if (l > 0 && l <=k&&gcd(k, l) == p[i])
mid[cnt2++] = l;
}
printf("Case #%d:\n", icase++);
printf("%d\n", cnt2);
if (cnt2!= 0)
{
printf("%lld", mid[0]);
for (int i =1; i < cnt2; i++)
printf(" %lld", mid[i]);
}
printf("\n");
}
}
一开始wa了几发,原因 在于gcd函数写错了
long long gcd(long long x, long long y)
{
return y ? gcd(y, x%y) : x;
//把x%y写成了y&x了,改过来之后成了x&y,导致还是错
}
接下来是 n是long long,又错了几发。
最终是过了,速度15ms,比暴力快了不少
#include<iostream>
#include<algorithm>
using namespace std;
int p[100];
int num[100];
long long mid[100000];
int cnt2 ;
long long n,cnt;
long long gcd(long long x, long long y)
{
return y ? gcd(y, x%y) : x;
}
void getp(long long n)
{
p[0] = 1;
num[0] = 1;
cnt = 1;
for (long long i = 2; i*i <= n; i++)
{
if (n%i == 0)
{
p[cnt] = i;
num[cnt] = 0;
while (n%i == 0)
{
num[cnt]++;
n /= i;
}
cnt++;
}
}
if (n > 1)
{
if (p[cnt - 1] == n)
num[cnt - 1]++;
else
{
p[cnt] = n;
num[cnt++] = 1;
}
}
}
void gao(int id, long long l)
{
long long s = n^l;
if (s > 0 && s <= n&&gcd(s, n) == l)
mid[cnt2++] = s;
long long m;
for (int i = id + 1; i < cnt; i++)
{
m = 1;
for (int j = 0; j < num[i]; j++)
{
m *= p[i];
gao(i, m*l);
}
}
}
int main()
{
int icase = 1;
while (~scanf("%lld",&n))
{
getp(n);
cnt2= 0;
gao(0, 1);
sort(mid, mid + cnt2);
cout << "Case #" << icase++ << ":" << endl;
cout << cnt2 << endl;
if (cnt2 != 0)
{
printf("%lld", mid[0]);
for (int i = 1; i < cnt2; i++)
printf(" %lld", mid[i]);
}
printf("\n");
}
return 0;
}