寒假ACM复习总结Day5-helman
这一天学的关于如何求找素数——埃氏筛,以及关于欧拉函数的运用
https://vjudge.net/contest/283625#problem/A
这道题就是欧拉函数的模板题,记住模板就行
需要注意的是要把x加减a,尽量让x非负最小
#include<bits/stdc++.h> using namespace std; int a,b; int x,y; int exgcd(int a,int b,int &x,int &y){ if(b==0){ x=1; y=0; return a; } int d=exgcd(b,a%b,x,y); int t=x; x=y; y=t-(a/b)*y; return d; } int main(){ while(cin>>a>>b){ int d=exgcd(a,b,x,y); if(d!=1)cout<<"sorry"<<endl; else { if(x>=0){ while(x>=b){ x-=b; y+=a; } } else { while(x<0){ x+=b; y-=a; } } cout<<x<<' '<<y<<endl; } } return 0; }
https://vjudge.net/contest/283625#problem/C
注意这道题,比较靠思维
将最左边看做0列,最下边看做0行
1行与1到n列都相连
2行与除了2的倍数都相连
3行与除了3的倍数都相连
而4行,不仅不与4的倍数相连,还不与2的倍数相连!!!
为什么呢,因为在4行2列前面已经有2行1列连过了
这样就发现,除了左下角的三个点,其他点行数与列数互质,没有除1外的公因数
#include<bits/stdc++.h> using namespace std; const int maxn=1007; int a[maxn]; void init(){ for(int i=1;i<maxn;i++)a[i]=i; for(int i=2;i<maxn;i+=2)a[i]/=2; for(int i=3;i<maxn;i+=2){ if(a[i]==i){ for(int j=i;j<maxn;j+=i) a[j]=a[j]/i*(i-1); } } } int c,m; int main(){ init(); cin>>c; for(int i=1;i<=c;i++){ cin>>m; int ans=0; for(int j=2;j<=m;j++) ans+=a[j]; cout<<i<<' '<<m<<' '<<(ans*2+3)<<endl; } return 0; }
https://vjudge.net/contest/283625#problem/D
这个题要找出一个数n,让a+n和b+n是相邻的素数
首先肯定要素数打表,然后要怎么做呢?
要很好的将输入的数据和素数联系起来,那就需要找出共同点
这个题的共同点的就是差,无论a,b要加个多么大的数才能变成素数,变成素数前后这两个数的差是不变的,所以我们可以根据差来存储素数,找到匹配相同差的最接近ab的素数就可以做出来了
#include<bits/stdc++.h> using namespace std; const int maxn=2e5; bool ispre[maxn]; int pre[maxn]; vector<int>v[151]; int cnt,t,a,b; void ini(){ cnt=0; for(int i=2;i<maxn;i++)ispre[i]=true; for(int i=2;i<maxn;i++){ if(ispre[i]==true){ pre[++cnt]=i; for(int j=i+i;j<maxn;j+=i) ispre[j]=false; } } } void init(){ ini(); for(int i=2;i<=cnt;i++){ int cmt=pre[i]-pre[i-1]; if(cmt<=150)v[cmt].push_back(pre[i]); } } int main(){ init(); cin>>t; for(int i=1;i<=t;i++){ int ans=-1; cin>>a>>b; int n=abs(a-b),m=max(a,b); for(int j=0;j<v[n].size();j++) if(v[n][j]>=m){ ans=v[n][j]-m; break; } cout<<"Case "<<i<<": "<<ans<<endl; } return 0; }