A
numbers, so neither 7 + 13 nor 3 + 5 + 5 + 7 is a valid representation for the integer 20.
Your mission is to write a program that reports the number of representations for the given positive integer.
2
3
17
41
20
666
12
53
0
1
1
2
3
0
0
1
2
/*
题目大意:一个数可以分成多个连续质数的和(包括这个数本身,算一种),求一共有多少种分法。
解题思路:先用素筛找到足够用的素数,然后暴力即可。
*/
#include <cstdio>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int mark[10010];
int prime[10010];
int Prime()
{
int index = 0;
memset(mark,0,sizeof(mark));
for(int i = 2;i<10010;i++)
{
if(mark[i]==0)
prime[index++] = i;
for(int j = 0;j<index&&prime[j]*i<10010;j++)
{
mark[i*prime[j]]=1; //所有素数的倍数一律去掉
if(i%prime[j]==0) //i%prime[j]==0 时 因为prime数组 中的素数是递增的,当 i 能整除 prime[j],
// 那么 i*prime[j+1] 这个合数肯定被 prime[j] 乘以某个数筛掉。
//因为i中含有prime[j], prime[j] 比 prime[j+1] 小。接下去的素数同理。所以不用筛下去了。
break;
}
}
return index;
}
int main()
{
int num;
while(cin>>num,num!=0)
{
Prime();
int sum=0,c=0,point=0;
for(int i=0;sum<=num&&prime[point]<=num;i++)
{
if(sum==num)
{
c++;
point++;
i=point-1;
sum=0;
continue;
}
if(sum+prime[i]>num&&sum<num) //i=point-1 指向下一个重新遍历
{
point++;
i=point-1;
sum=0;
continue;
}
sum+=prime[i];
}
cout<<c<<endl;
}
return 0;
}
B
Your program is given 2 numbers: L and U (1<=L< U<=2,147,483,647), and you are to find the two adjacent primes C1 and C2 (L<=C1< C2<=U) that are closest (i.e. C2-C1 is the minimum). If there are other pairs that are the same distance apart, use the first pair. You are also to find the two adjacent primes D1 and D2 (L<=D1< D2<=U) where D1 and D2 are as distant from each other as possible (again choosing the first pair if there is a tie).
2 17 14 17
2,3 are closest, 7,11 are most distant. There are no adjacent primes.
/*
题目大意:给一个范围L~U,输出其中相邻质数差值最大的和最小的,结果相同输出第一组
解题思路:还是素筛+暴力,但是这个题数据范围很大,需要进行优化。
第一是求出int范围内的素数,没办法直接开那么大的数组,如果一个合数的一个公因数大于2^16,那么另一个公因数必定小于2^16次方,所以求出2^16次方内的素数,
然后通过乘倍数,找到int范围内的合数,用f标记一下,未标记的就是素数了。
第二是数组下标需要优化,下标无法直接用L~U,因此做一个转移,变成0~U-L。
*/
#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <cstdio>
#define Max 65536
using namespace std;
int mark[Max];
int prime[Max];
int f[1000010];
int index = 0;
void Prime() //筛除65536以内的质数
{
memset(mark,0,sizeof(mark));
for(int i = 2;i<Max;i++)
{
if(mark[i]==0)
prime[index++]=i;
for(int j = 0;j<index&&i*prime[j]<Max;j++)
{
mark[i*prime[j]]=1;
if(i%prime[j]==0)
break;
}
}
}
int main()
{
int l,u;
Prime();
while(cin>>l>>u)
{
memset(f,0,sizeof(f));
if(l==1) l=2;
for(int i = 0;i<index;i++)
{
int a = l/prime[i];
int b = u/prime[i];
for(int j = a;j<=b;j++)
{
if(j>1)
f[j*prime[i]-l] = 1; //所有范围内质数的倍数一律标记为1
}
}
int n=-1,max_=-1,min_=1e9,min_1,min_2,max_1,max_2; //max min 记录差值, _1 _2记录数
for(int i = 0;i<=u-l;i++)
{
if(f[i]==0) //保证仅对素数进行操作
{
if(n==-1)
{
n=i;continue;
}
if(max_<i-n) //因为相同数据取第一组,所以用<而非≤
{
max_=i-n; max_1=n+l; max_2=i+l; //记录时记得把偏移量再加回来!
}
if(min_>i-n)
{
min_=i-n; min_1=n+l; min_2=i+l;
}
n=i;
}
}
if(max_==-1)
cout<<"There are no adjacent primes.\n";
else
printf("%d,%d are closest, %d,%d are most distant.\n",min_1,min_2,max_1,max_2);
}
return 0;
}
C
Each player chooses two numbers Ai and Bi and writes them on a slip of paper. Others cannot see the numbers. In a given moment all players show their numbers to the others. The goal is to determine the sum of all expressions Ai Bi from all players including oneself and determine the remainder after division by a given number M. The winner is the one who first determines the correct result. According to the players' experience it is possible to increase the difficulty by choosing higher numbers.
You should write a program that calculates the result and is able to find out who won the game.
(A1B1+A2B2+ ... +AHBH)mod M.
3 16 4 2 3 3 4 4 5 5 6 36123 1 2374859 3029382 17 1 3 18132
2 13195 13
/*
题目大意:计算 (A1^B1+A2^B2+ ... +AH^BH)mod M.
解题思路:裸的快速幂 直接套公式.... QAQ不过我好像理解不够深刻 什么同余公式什么转换blabla的。。有点蒙...
*/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
using namespace std;
int pow_mod(int a,int b,int m) //快速幂套路
{
int ans = 1;
a=a%m;
while(b>0)
{
if(b%2==1)
ans=(ans*a)%m;
b=b/2;
a=(a*a)%m;
}
return ans;
}
int main()
{
int T;
cin>>T;
while(T--)
{
int mod;cin>>mod;
int n;cin>>n;
int ans=0;
while(n--)
{
int a,b; cin>>a>>b;
ans += pow_mod(a,b,mod);
}
cout<<ans%mod<<endl;
}
}
Fermat's theorem states that for any prime number p and for any integer a > 1, ap =a (mod p). That is, if we raise a to the pth power and divide by p, the remainder isa. Some (but not very many) non-prime values of p, known as base-a pseudoprimes, have this property for some a. (And some, known as Carmichael Numbers, are base-apseudoprimes for all a.)
Given 2 < p ≤ 1000000000 and 1 < a < p, determine whether or not p is a base-apseudoprime.
Input contains several test cases followed by a line containing "0 0". Each test case consists of a line containing p and a.
For each test case, output "yes" if p is a base-a pseudoprime; otherwise output "no".
3 2 10 3 341 2 341 3 1105 2 1105 3 0 0
no no yes no yes yes
/*
题目大意:如果pow(a,p)=a%p 并且p不是素数,输出yes 否则输出no 0 0 结束输入
解题思路:一个需要开longlong快速幂..
*/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
using namespace std;
long long pow_mod(long long a,long long b,long long m) //快速幂
{
long long ans = 1;
a=a%m;
while(b>0)
{
if(b%2==1)
ans=(ans*a)%m;
b=b/2;
a=(a*a)%m;
}
return ans;
}
bool isPrime(long long a) //判断素数
{
for(long long i = 2;i<=(long long)sqrt((double)a)+1;i++) //!!!sqrt(double)...需要cast一下
{
if(a%i==0)
return false;
}
return true;
}
int main()
{
long long p,a;
while(cin>>p>>a)
{
if(a==0&&p==0)
{
return 0;
}
if(isPrime(p))
{
cout<<"no"<<endl;
}
else
{
if(pow_mod(a,p,p)==a)
cout<<"yes"<<endl;
else
cout<<"no"<<endl;
}
}
return 0;
}
E
我们把这两只青蛙分别叫做青蛙A和青蛙B,并且规定纬度线上东经0度处为原点,由东往西为正方向,单位长度1米,这样我们就得到了一条首尾相接的数轴。设青蛙A的出发点坐标是x,青蛙B的出发点坐标是y。青蛙A一次能跳m米,青蛙B一次能跳n米,两只青蛙跳一次所花费的时间相同。纬度线总长L米。现在要你求出它们跳了几次以后才会碰面。
1 2 3 4 5
4
/*
题目大意:愉快的中文题,俩青蛙均在一个长L的纬线上,各自有一个跳跃能力,从不同点开始相向跳,求它俩跳多少次才能在一起....不能就输出“Impossible”
解题思路:拓展欧几里德算法....还是有点懵逼
跳t次,只要满足 x+tm -(y+tn)= pL (p∈Z)即可,化简一下(n-m)t +Lp = x-y
设n-m=A x-y=B 即求At+Lp=B 即At=B(mod L) QAQ这个膜的不大懂....然后就可以exgcd了。。。
*/
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
using namespace std;
long long x,y,m,n,l,a,b;
long long ex_gcd(long long a,long long b,long long &x,long long &y)
{
long long t,d;
if (b==0)
{
x=1; y=0; return a;
}
d=ex_gcd(b,a%b,x,y);
t=x; x=y; y=t-a/b*y;
return d;
}
int main()
{
long long ar,br;
while(cin>>x>>y>>m>>n>>l)
{
long long M = ex_gcd(n-m,l,ar,br);
if((x-y)%M||m==n) //因为起点不同,所以跳跃能力相同 或者 求模不是整数圈均不可能
{
cout<<"Impossible"<<endl;
}
else
{
long long s = l/M; //这一部分也有点不太懂。 有空再研究研究
ar = ar*((x-y)/M);
ar = (ar%s+s)%s;
cout<<ar<<endl;
}
}
}