uva Mathematics :: Basic Problems

Root :: AOAPC I: Beginning Algorithm Contests -- Training Guide (Rujia Liu) :: Chapter 2. Mathematics :: Basic Problems


11388 - GCD LCM

#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;
}


11889 - Benefit

// 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;
}


10943 - How do you add?

// 组合数学,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;
}


10780 - Again Prime? No Time.

// 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;
}


10892 - LCM Cardinality

// 先打素数表,质因式分解
// 对于每个素数的幂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;
}


11752 - The Super Powers

#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;
}


11076 - Add Again

// 组合计数
#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;
}


11609 - Teams

// 快速幂
#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;
}


12050 - Palindrome Numbers

// 第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;
}


11489 - Integer Game

// 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;
}


10791 - Minimum Sum LCM

// 质因式分解
/// 两组数据比较恶心,一个是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;
}


11461 - Square Numbers

// 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;
}


1315 - Crazy tea party

// 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;
}


10339 - Watching Watches

#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;
}


10367 - Equations

http://blog.csdn.net/shiyuankongbu/article/details/8742042


10586 - Polynomial Remains

#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;
}


10693 - Traffic Volume

// 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;
}


10726 - Coco Monkey

经典问题 ? 暂时不会做


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;
}


11029 - Leading and Trailing

#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;
}


11314 - Hardly Hard

// 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;
}


10995 - Educational Journey

这个题。。。给你t1  t2  t3  t4  t5 分别表示a追上c m d 的时间 ,以及 d 追上 c m 的时间 , 求c 遇到 m 的时间。。。方程不好列,胖子给的方程把我弄乱了,不会做


1319 - Maximum

神题 ? 应该是极值之类的东西吧,高数没学好,不会。。。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值