这道题一开始一直tle
我们不停地尝试n的范围,从1到10000等等一直改变为(k异或m)除以二 到(k异或m)
还是会tle
一开始的代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int divisor(ll a,ll b)
{
ll temp;
if(a<b)
{
temp=a;a=b;b=temp;
}
while(b!=0)
{
temp=a%b;
a=b;
b=temp;
}
return a;
}
int main()
{
ll T;
cin >> T ;
while(T--)
{
ll k,m;
cin >> k >> m ;
ll cot=0;
ll sum=0;
ll n=-1;
ll q=k^m;
ll b=k&m;
if(b==0) b+=1;
for(ll i=b;i<=q;i++)
{
cot=0;
for(ll j=i+1;cot!=m;j++)
{
if(divisor(j,i)==1)
{
// printf("i==%5d,j==%5d\n",i,j);
cot++;
}
if(cot==m)
{
sum=j;
break;
}
}
// printf("%d\n",sum);
// printf("%d\n",sum-i);
// printf("%d\n",(sum-i)^i);
// printf("%d\n",6^5);
if(((sum-i)^i)==k)
{
// printf("%d %d\n",(sum-i)^i,k);
n=i;
break;
}
}
printf("%lld\n",n);
}
return 0;
}
由于我们输出了100个互质数,通过观察他们的范围,发现他们最多不超过400,于是我们把遍历n的范围缩小至上下512岂可AC
附上原创AC代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int divisor(ll a,ll b)
{
ll temp;
if(a<b)
{
temp=a;a=b;b=temp;
}
while(b!=0)
{
temp=a%b;
a=b;
b=temp;
}
return a;
}
int main()
{
ll T;
cin >> T ;
while(T--)
{
ll k,m;
cin >> k >> m ;
ll cot=0;
ll sum=0;
ll n=-1;
ll q=k^m;
ll b=k&m;
if(b==0) b+=1;
for(ll i=(-512+k);i<=(512+k);i++)
{
if(i<1) continue;
cot=0;
for(ll j=i+1;cot!=m;j++)
{
if(divisor(j,i)==1)
{
// printf("i==%5d,j==%5d\n",i,j);
cot++;
}
if(cot==m)
{
sum=j;
break;
}
}
// printf("%d\n",sum);
// printf("%d\n",sum-i);
// printf("%d\n",(sum-i)^i);
// printf("%d\n",6^5);
if(((sum-i)^i)==k)
{
// printf("%d %d\n",(sum-i)^i,k);
n=i;
break;
}
}
printf("%lld\n",n);
}
return 0;
}