A.Prime Independence(素数筛法+最大独立集)
算法还没研究明白,贴个链接。
http://www.2cto.com/kf/201506/404426.html
B.Pairs Forming LCM(素因子分解)
http://blog.csdn.net/lbbbbpro029/article/details/50897669
C.Sigma Function(素因子分解+各种公式+筛数)
http://blog.csdn.net/lbbbbpro029/article/details/50912804
D.Harmonic Number(暴力)
本来以为和调和级数的公式有关,结果好像就是一个暴力,通过T<10000压缩内存进行递推。
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
using namespace std;
struct sb
{
int no,n;
double r;
}inp[10005];
bool cmp1(sb a,sb b)
{
return a.n<b.n;
}
bool cmp2(sb a,sb b)
{
return a.no<b.no;
}
void solve(int n)
{
double l1=0,l2;
int cnt=0;
for(int i=1;i<=n;i++)
{
l2=l1+1.0/i;
l1=l2;
while(inp[cnt].n==i)
{
inp[cnt].r=l1;
cnt++;
}
}
}
int main()
{
//double c=0.57721566490;
int n,x;
while(~scanf("%d",&n))
{
for(int i=0;i<n;i++)
scanf("%d",&inp[i].n),inp[i].no=i;
sort(inp,inp+n,cmp1);
solve(inp[n-1].n);
sort(inp,inp+n,cmp2);
for(int i=0;i<n;i++)
printf("Case %d: %.10f\n",i+1,inp[i].r);
}
return 0;
}
E.Help Hanzo(素数筛选)
尝试用了下Robin-Miller素数测试的方法判断素数,但是还是超时。
于是利用b-a《=100000来压缩内存,用i-a作为数字i的下标进行区间范围内的素数筛选
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
using namespace std;
const int MAXN=160000;
int p[MAXN];
bool valid[MAXN];
bool tt[500000];
int tot;
void get()
{
memset(valid,true,sizeof(valid));
for(int i=2; i<=MAXN; i++)
{
if(valid[i])
{
tot++;
p[tot]=i;
}
for(int j=1; ((j<=tot)&&(i*p[j]<=MAXN)); j++)
{
valid[i*p[j]]=false;
if(i*p[j]==0) break;
}
}
}
void test(long long a,long long b)
{
memset(tt,true,sizeof(tt));
for(int j=1; j<tot; j++)
{
if(p[j]*p[j]>b) break;
long long k;
if(a%p[j]==0)
k=a;
else
k=(a/p[j]+1)*p[j];
if(k==p[j]) k+=p[j];
//cout<<k<<endl;
for(; k<=b; k+=p[j])
{
int d=(long long)(k-a);
//cout<<d<<endl;
tt[d]=false;
}
}
}
int main()
{
get();
int T,c=1;
long long a,b;
scanf("%d",&T);
while(T--)
{
scanf("%I64d%I64d",&a,&b);
test(a,b);
int ans=0;
for(int i=0; i<=b-a; i++)
if(tt[i]) ans++;
if(a==1) ans--;
printf("Case %d: %d\n",c++,ans);
//for(int i=0; i<=b-a; i++)
//cout<<tt[i]<<endl;
}
return 0;
}
F.Maximum GCD(欧几里得算法)
用字符串处理一行数字,直接枚举即可。
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
int gcd(int a,int b)
{
return b==0?a:gcd(b,a%b);
}
int main()
{
int n;
int a[1000];
char c[1000],d[100000];
while(~scanf("%d",&n))
{
getchar();
while(n--)
{
gets(d);
int cnt=0,con=0;
for(int i=0;i<=strlen(d);i++)
{
if(d[i]>='0'&&d[i]<='9')
c[cnt++]=d[i];
else
{
if(cnt==0) continue;
c[cnt++]=0;
a[con++]=atoi(c);
cnt=0;
}
}
//for(int i=0;i<con;i++)
//cout<<a[i]<<endl;
int maxn=0;
for(int i=0;i<con;i++)
for(int j=i+1;j<con;j++)
if(gcd(a[i],a[j])>maxn)
maxn=gcd(a[i],a[j]);
printf("%d\n",maxn);
}
}
return 0;
}
G.Code Feat(中国剩余定理+DFS)
dfs的写法在研究中...贴个链接
http://blog.csdn.net/a601025382s/article/details/9732779
H.The equation(拓展欧几里得)
负数的情况通过改变取值区间(变动坐标轴)的方法凑出ax+by=c的情况,找到一组在取值区间的内的解,暴力求解。
#include <iostream>
#include <stdio.h>
using namespace std;
long long exgcd(long long a,long long b,long long &x,long long &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
else
{
long long r=exgcd(b,a%b,y,x);
y-=x*(a/b);
return r;
}
}
int main()
{
long long a,b,c,x1,x2,y1,y2,t,x,y;
while(scanf("%I64d%I64d%I64d",&a,&b,&c)==3)
{
scanf("%I64d%I64d%I64d%I64d",&x1,&x2,&y1,&y2);
if(a==0&&b!=0)
{
printf("%I64d\n",x2-x1+1);
continue;
}
if(b==0&&a!=0)
{
printf("%I64d\n",y2-y1+1);
continue;
}
if(a==0&&b==0)
{
if(c==0)
{
printf("%I64d\n",(x2-x1+1)*(y2-y1+1));
}
else
printf("0\n");
continue;
}
if(c>0)
{
a=-a;
b=-b;
}
else
c=-c;
if(a<0)
{
t=x1;
x1=-x2;
x2=-t;
a=-a;
}
if(b<0)
{
t=y1;
y1=-y2;
y2=-t;
b=-b;
}
long long r=exgcd(a,b,x,y);
if(c%r!=0)
{
printf("0\n");
continue;
}
a=a/r;
b=b/r;
c=c/r;
while(x<x1)
{
x+=b;
y-=a;
}
while(x>x2)
{
x-=b;
y+=a;
}
long long ans=0;
x*=c;
y*=c;
while(x<=x2)
{
if(ans)break;
if(x>=x1&&x<=x2&&y>=y1&&y<=y2)
ans++;
if(ans)break;
x+=b;
y-=a;
}
while(x>=x1)
{
if(ans)break;
if(x>=x1&&x<=x2&&y>=y1&&y<=y2)
ans++;
if(ans)break;
x-=b;
y+=a;
}
if(ans)
{
long long a1=(x2-x)/b;
long long b1=(y-y1)/a;
ans+=min(a1,b1);
a1=(x-x1)/b;
b1=(y2-y)/a;
ans+=min(a1,b1);
}
printf("%I64d\n",ans);
}
return 0;
}