Root :: AOAPC I: Beginning Algorithm Contests -- Training Guide (Rujia Liu) :: Chapter 2. Mathematics :: Basic Problems
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int gcd(int a,int b)
{
if(b==0)
return a;
return gcd(b,a%b);
}
int lcm(int a,int b)
{
return a/gcd(a,b)*b;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int a,b;
scanf("%d%d",&a,&b);
if(gcd(a,b)==a&&lcm(a,b)==b)
printf("%d %d\n",a,b);
else
printf("-1\n");
}
return 0;
}
// water
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
int gcd(int a,int b)
{
if(b==0)
return a;
return gcd(b,a%b);
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int a,b,c;
scanf("%d%d",&a,&c);
if(c%a!=0)
{
printf("NO SOLUTION\n");
continue;
}
int cnt=c/a;
int tag=1;
b=cnt;
while(gcd(a,b)*cnt!=b)
{
b+=cnt;
if(b>c)
{
tag=0;
break;
}
}
if(tag==0)
{
printf("NO SOLUTION\n");
continue;
}
else
printf("%d\n",b);
}
return 0;
}
// 组合数学,n个数放进k个盒子
// C(n+k-1,k-1)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define mod 1000000
int f[210][210];
void init()
{
memset(f,0,sizeof(f));
f[0][0]=0;
for(int i=1;i<210;i++)
f[i][0]=f[i][i]=1;
for(int i=1;i<210;i++)
for(int j=1;j<i;j++)
f[i][j]=(f[i-1][j]+f[i-1][j-1])%mod;
}
int main()
{
int n,k;
init();
while(scanf("%d%d",&n,&k)!=EOF)
{
if(n==0&&k==0)
break;
printf("%d\n",f[n+k-1][k-1]);
}
return 0;
}
// prime
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <iostream>
using namespace std;
#define maxn 10000
int vis[maxn];
static int n_prime=0;
const int total=1230; // 1w内1229个素数
int prime[total];
int s[total];
int b[total];
int m,n;
void pre_solve()
{
memset(vis,1,sizeof(vis));
vis[0]=vis[1]=0;
for(int i=2;i<maxn;i++)
if(vis[i])
{
prime[++n_prime]=i;
for(int j=2*i;j<=maxn;j+=i)
vis[j]=0;
}
}
void solve()
{
memset(s,0,sizeof(s));
memset(b,0,sizeof(b));
for(int i=1;i<=n;i++)
{
int cnt=i;
for(int j=1;j<total;j++)
{
if(prime[j]>cnt)
break;
if(cnt%prime[j]==0)
{
while(cnt%prime[j]==0)
{
s[j]++;
cnt/=prime[j];
}
}
}
}
int tmp=m;
for(int i=1;i<total;i++)
{
if(tmp<prime[i])
break;
if(tmp%prime[i]==0)
{
while(tmp%prime[i]==0)
{
b[i]++;
tmp/=prime[i];
}
}
}
long long ans=1;
ans<<=63;
ans--;
long long aa=ans;
int tag=0;
for(int i=1;i<total;i++)
{
if(b[i]!=0)
{
if(s[i]==0)
{
tag=0;
break;
}
tag=1;
ans=min(ans,(long long)s[i]/b[i]);
//printf("%d....%d\n",s[i],b[i]);
}
}
if(ans==aa||tag==0)
printf("Impossible to divide\n");
else
printf("%lld\n",ans);
}
int main()
{
pre_solve();
int t;
scanf("%d",&t);
for(int cases=1;cases<=t;cases++)
{
scanf("%d%d",&m,&n);
printf("Case %d:\n",cases);
solve();
}
return 0;
}
// 先打素数表,质因式分解
// 对于每个素数的幂x,两个数字需满足:
// 两个数字的幂加起来等于x,或者一个等于x,另外一个小于等于x
// 不等的情况有2*x种,相等的只有1种,就是(2*x+1)
// 然后乘法定理,全部累乘
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
#define maxn 100001
int vis[100001];
int n_prime;
int prime[maxn];
int cnt[maxn];
long long n;
void set_prime()
{
n_prime=0;
memset(vis,1,sizeof(vis));
vis[0]=vis[1]=0;
for(int i=2;i<100001;i++)
if(vis[i])
{
prime[++n_prime]=i;
for(int j=2*i;j<100001;j+=i)
vis[j]=0;
}
}
void solve()
{
memset(cnt,0,sizeof(cnt));
long long tmp=n;
for(int i=1;i<=n_prime;i++)
{
if(tmp<prime[i])
break;
if(tmp%prime[i]==0)
{
while(tmp%prime[i]==0)
{
tmp/=prime[i];
cnt[i]++;
}
}
}
if(tmp>100000)
cnt[0]++;
long long ans=1;
for(int i=0;i<=n_prime;i++)
if(cnt[i]!=0)
{
//printf("%d ... %lld \n",cnt[i],ans);
ans*=(2*cnt[i]+1);
}
printf("%lld\n",ans/2+1);
}
int main()
{
set_prime();
while(scanf("%lld",&n)!=EOF,n)
{
printf("%lld ",n);
solve();
}
return 0;
}
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <set>
using namespace std;
set<unsigned long long>s;
#define maxn 66
int vis[maxn];
void pre_solve()
{
memset(vis,1,sizeof(vis));
vis[0]=vis[1]=0;
for(int i=2;i*i<=maxn;i++)
if(vis[i])
{
for(int j=2*i;j<maxn;j+=i)
vis[j]=0;
}
}
int main()
{
pre_solve();
for(int i=2;;i++)
{
unsigned long long tmp=i;
int lim=ceil(64*log(2.0)/log(i*1.0));
if(lim<=3)
break;
unsigned long long tag=i;
for(int j=2;j<lim;j++)
{
tag*=tmp;
if(vis[j]==0)
s.insert(tag);
}
}
printf("1\n");
set<unsigned long long>::iterator it=s.begin();
for(;it!=s.end();it++)
printf("%llu\n",*it);
return 0;
}
// 组合计数
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <map>
#include <cstring>
#include <cmath>
using namespace std;
map<unsigned long long,int>m;
unsigned long long fac(int n)
{
unsigned long long ans=1;
for(int i=1;i<=n;i++)
ans*=i;
return ans;
}
int main()
{
int n;
while(scanf("%d",&n),n!=0)
{
m.clear();
unsigned long long num;
unsigned long long sum=0;
unsigned long long ans=1;
for(int i=1;i<=n;i++)
{
scanf("%llu",&num);
sum+=num;
m[num]++;
}
for(int i=1;i<=n;i++)
ans*=10;
ans--;
ans/=9;
unsigned long long tmp=fac(n-1);
tmp*=sum;
map<unsigned long long ,int>::iterator it;
for(it=m.begin();it!=m.end();it++)
tmp/=fac(it->second);
tmp*=ans;
printf("%llu\n",tmp);
}
return 0;
}
// 快速幂
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
#define mod 1000000007
long long Pow(long long a,long long b)
{
long long ans=1;
while(b)
{
if(b&1)
{
b--;
ans=(ans*a)%mod;
}
else
{
b/=2;
a=(a*a)%mod;
}
}
return ans;
}
int main()
{
int t;
scanf("%d",&t);
for(int cases=1;cases<=t;cases++)
{
long long n;
scanf("%lld",&n);
long long ans=Pow((long long)2,n-1);
ans=(ans*n)%mod;
printf("Case #%d: %lld\n",cases,ans);
}
return 0;
}
// 第n大回文数
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
//http://mathworld.wolfram.com/PalindromicNumber.html
// 根据这个性质,求得第n个回文数的digit
long long Pow(int n)
{///算10^n的大小
long long ans=1;
long long ten=10;
while(n)
{
if(n&1)
{
n--;
ans*=ten;
}
else
{
n/=2;
ten*=ten;
}
}
return ans;
}
long long sum(int n)
{//求10^n内回文数的个数
long long ans=1;
if(n&1)
{
ans*=11;
ans*=Pow((n-1)/2);
ans-=2;
}
else
{
ans=Pow(n/2);
ans--;
ans*=2;
}
return ans;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF,n)
{
int cnt=1;
while(sum(cnt)<n)
cnt++;
n-=sum(cnt-1);
//printf("%d == %d\n",cnt,n);
// 得到该数量级的第n个数
if(cnt&1)//奇数位个数字
{
// 分成 (cnt-1)/2,1,(cnt-1)/2三部分
long long tmp=(cnt-1)/2;
if(tmp==0)
{
printf("%d\n",n);
continue;
}
else
{
tmp=9*Pow(tmp-1);//首位非0,其余位均有10种可能
//printf("左边位数tmp=%d\n",tmp);
int pp=(n-1)/10;
if((cnt-1)/2-1>=0)
pp+=Pow((cnt-1)/2-1);
//printf("pp=%d\n",pp);
n=(n%10);
if(n==0)
n+=10;
int mid=(n-1)%(10);//得到中间数字
//printf("mid=%d\n",mid);
printf("%d%d",pp,mid);
while(pp)
{
printf("%d",pp%10);
pp/=10;
}
printf("\n");
}
}
else //偶数位个数字
{
//分成 cnt/2 和 cnt/2 位
int tmp=cnt/2;
//printf("tmp=%d\n",tmp);
int pp=Pow(tmp-1);
pp+=n-1;
printf("%d",pp);
while(pp)
{
printf("%d",pp%10);
pp/=10;
}
printf("\n");
}
}
return 0;
}
// game
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int a[3];
char s[1001];
int main()
{
int T;
scanf("%d",&T);
for(int t=1;t<=T;t++)
{
scanf("%s",s);
memset(a,0,sizeof(a));
int l=strlen(s);
int sum=0;
for(int i=0;i<l;i++)
{
sum+=(s[i]-'0');
a[(s[i]-'0')%3]++;
}
int tag=1;
/// S--first
if(sum%3==0)
{/// 3321 3312 333 33
if(a[0]%2==0) // 3的倍数存在偶数个
tag=0;// 先手输
else
tag=1;
}
else if(sum%3==1)
{
if(a[1]) //除去全部是3的剩下的存在余1的 331
if(a[0]%2) // 这种情况下,前面偶数个3不看,最后剩下(3n+1)个1和一个三,拿走一个1,先手输
tag=0;
else
tag=1;
else // 3322 这种也是先手输
tag=0;
}
else if(sum%3==2)// 除去全是3的剩下的存在 3n+1+1 或者 3n+2
{
if(a[2]) // 3n+2
if(a[0]%2)// 去掉偶数个3后,留下一个2和3,先手输
tag=0;
else ;
else // 3n+1+1的情况, 11
tag=0;
}
printf("Case %d: ",t);
if(tag)
printf("S\n");
else
printf("T\n");
}
return 0;
}
// 质因式分解
/// 两组数据比较恶心,一个是1(输出2,不是0)
/// 另一个是2^31-1,如果用int,直接输出-2^31,呵呵
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#define maxn 65536
int vis[maxn];
int prime[6544];
int n_prime=0;
int a[6544];
void Prime()
{
memset(vis,1,sizeof(vis));
vis[0]=vis[1]=0;
for(int i=2;i<maxn;i++)
if(vis[i])
{
prime[++n_prime]=i;
for(int j=2*i;j<maxn;j+=i)
vis[j]=0;
}
//printf("%d\n",n_prime);
}
long long Pow(long long a,long long b)
{
long long ans=1;
while(b)
{
if(b&1)
{
b--;
ans*=a;
}
else
{
b/=2;
a*=a;
}
}
return ans;
}
int main()
{
int t=0;
Prime();
long long n;
//printf("%d\n",prime[n_prime]);
while(scanf("%lld",&n),n)
{
printf("Case %d: ",++t);
if(n==1)
{
printf("2\n");
continue;
}
memset(a,0,sizeof(a));
long long ans=0;
int cnt=0;
for(int i=1;i<=n_prime;i++)
{
if(n%prime[i]==0)
{
cnt++;
while(n%prime[i]==0)
{
n/=prime[i];
a[i]++;
}
}
if(prime[i]>n)
break;
}
for(int i=1;i<=n_prime;i++)
if(a[i])
{
ans+=Pow(prime[i],a[i]);
}
if(n>prime[n_prime])
{
if(ans==0)
ans=(n+1);
else
ans+=n;
}
if(cnt==1)
ans++;
printf("%lld\n",ans);
}
return 0;
}
// floor
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
int main()
{
int a,b;
while(scanf("%d%d",&a,&b)!=EOF)
{
if(a==0&&b==0)
return 0;
if(a==0)
printf("%.lf\n",floor(sqrt(b)));
else
printf("%.lf\n",floor(sqrt(b))-floor(sqrt(a-1)));
}
return 0;
}
// water
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
long long sum(int n)
{
long long ans=0;
for(int i=1;i<=n;i++)
ans+=i;
return ans;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
int cnt=n/2;
int tmp=n-cnt;
long long ans=sum(tmp-1)+sum(cnt-1);
printf("%lld\n",ans);
}
return 0;
}
#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
int main()
{
long long a,b;
while(scanf("%lld%lld",&a,&b)!=EOF)
{
if(a==b)
{
printf("%lld %lld ",a,b);
printf("12:00\n");
continue;
}
long long cnt=(86400-a)*43200;
long long tmp=60*fabs(a-b+0.0);
long long ans=cnt/tmp;
if((cnt%tmp)*2>=tmp)
ans++;
printf("%lld %lld ",a,b);
printf("%02lld:%02lld\n",((ans/60)%12==0)?(ans/60%12+12):(ans/60%12),ans%60);
}
return 0;
}
http://blog.csdn.net/shiyuankongbu/article/details/8742042
#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
#include <stack>
using namespace std;
int main()
{
int n,k;
while(scanf("%d%d",&n,&k)!=EOF)
{
if(n==-1&&k==-1)
break;
vector<long long>a(n+1);
for(int i=0;i<=n;i++)
scanf("%lld",&a[i]);
reverse(a.begin(),a.end());
int cnt=0;
while(cnt<a.size()&&a[cnt]==0)
cnt++,n--;
while(n>=k)
{
a[cnt+k]-=a[cnt];
cnt++,n--;
}
while(cnt<a.size()&&a[cnt]==0)
cnt++,n--;
stack<long long>s;
while(cnt<a.size())
s.push(a[cnt++]);
bool tag=true;
while(!s.empty())
{
if(tag)
{
printf("%lld",s.top());
s.pop();
tag=false;
}
else
{
printf(" ");
printf("%lld",s.top());
s.pop();
}
}
if(tag)
printf("0");
printf("\n");
}
return 0;
}
// water
#include <cstdio>
#include <cmath>
#include <iostream>
using namespace std;
int main()
{
double l,f;
while(scanf("%lf%lf",&l,&f)!=EOF,l!=0,f!=0)
{
double v=sqrt(2.0*l*f);
printf("%.8lf ",v);
printf("%.8lf\n",v*3600/(2*l));
}
return 0;
}
经典问题 ? 暂时不会做
10773 - Back to Intermediate Math
// 这个题考查精度?
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#define eps 1e-4
using namespace std;
int main()
{
int T,t;
scanf("%d",&T);
double d,u,v;
for(t=1;t<=T;t++)
{
scanf("%lf%lf%lf",&d,&v,&u);
printf("Case %d: ",t);
if(u-v<=eps||u<=eps||v<=eps)
printf("can't determine\n");
else
{
double s1=d/u;
double s2=d/sqrt(u*u-v*v);
printf("%.3lf\n",s2-s1);
}
}
return 0;
}
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
int Pow(int a,int b)
{
int ans=1;
while(b)
{
if(b&1)
{
b--;
ans=(ans*a)%1000;
}
else
{
b/=2;
a=(a*a)%1000;
}
}
return ans%1000;
}
int main()
{
int t;
while(scanf("%d",&t)!=EOF)
{
while(t--)
{
long long n,k;
scanf("%lld%lld",&n,&k);
int di=n%1000;
di=Pow(di,k);
//printf("%d\n",di);
double gao=k*log(n+0.0)/log(10.0);
gao=gao-ceil(gao);
gao=pow(10.0,gao);
gao*=1000;
printf("%03d...%03d\n",(int)gao,di);
}// 呃 ,WA了好多次,原来是低位的前置0掉了
}
return 0;
}
// water
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <iostream>
using namespace std;
struct point
{
double x,y;
};
point a,b;
int main()
{
int t;
double ans;
scanf("%d",&t);
while(t--)
{
scanf("%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y);
ans=sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
ans+=sqrt((a.x+b.x)*(a.x+b.x)+(a.y+b.y)*(a.y+b.y));
printf("%.3lf\n",ans);
}
return 0;
}
这个题。。。给你t1 t2 t3 t4 t5 分别表示a追上c m d 的时间 ,以及 d 追上 c m 的时间 , 求c 遇到 m 的时间。。。方程不好列,胖子给的方程把我弄乱了,不会做
神题 ? 应该是极值之类的东西吧,高数没学好,不会。。。