• 【2018年全国多校算法寒假训练营练习比赛(第三场)】


    之前题目比较水,今天的还可以。

    【A 不凡的大夫】

    方法一:答案是log8(n!),解决方案是预处理,将需要的答案记录下来以免超内存;

    方法二:用公式,斯特林公式:   n! approx sqrt{2pi n}\, left(frac{n}{e}
ight)^{n}.

    【B 一个小问题】

    题解:线性同余方程组,一看就不是中国剩余定理,当心。

    【C 守护白起】

    题解:polya。。。。。比赛的时候忘记加逆元。。。mmp,然后WA了,后面来不及了。

    【D 小牛vs小客】

    题解:对称博弈,做过不久,先考虑特殊情况,再考虑对称性。

    【E 进击吧!阶乘】

    题解:高精度裸题,py可以直接码。

    【F 小牛再战】

    题解:博弈,好像和奇偶有关。

    【G 大水题】

    题解:简单容斥定理。

    【H 向左走】

    一眼不会题。。。。。。。

    【I 三角形】

    题解:面积可以用海伦公式或者向量法,(自己习惯向量法);GCD求线段上整点;皮克定理求内部整点。

    --------------------------------------------------分界线--------------------------------------------------------------

    对于一个数学不好的人(队伍)来说,这次是敲响了警钟。!

    上面的东西会尽快补齐的。

    【A】预处理:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<ctime>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<string>
    using namespace std;
    int N;
    struct query{
        int id,num;
        bool friend operator<(const query&A,const query&B)
        {return A.num<B.num;}
    }q[1000010];
    int ans[1000010];
    int main(){
        scanf("%d",&N);
        for(int i=1;i<=N;i++)
            scanf("%d",&q[i].num),q[i].id=i,q[i].num;
        sort(q+1,q+1+N);
        int now=1,cnt=1;
        double temp=3;
        while(q[now].num==0)
            ans[q[now++].id]=1;
        for(int i=1;i<=q[N].num;i++){
            temp=temp+log2(1.0*i);
            while(q[now].num==i)
                ans[q[now++].id]=temp/3;
        }
        for(int i=1;i<=N;i++)
            printf("%d
    ",ans[i]);
        return 0;
    }
    View Code

    斯特林:

    【B】求解线性同余方程组

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<iostream>
    #define ll long long
    using namespace std;
    void Ex_gcd(ll a,ll b,ll &d,ll &x,ll &y)
    {
        if(b==0){ d=a; x=1; y=0; return ;}
        Ex_gcd(b,a%b,d,y,x); y-=a/b*x;
    }
    int main()
    {
        ll c1,c2,c,a,b,d,x,y,n;
        while(~scanf("%lld",&n)){
            bool Flag=false;
            scanf("%lld%lld",&a,&c1);
            for(int i=2;i<=n;i++) {
                scanf("%lld%lld",&b,&c2);
                if(Flag) continue; c=c2-c1;
                Ex_gcd(a,b,d,x,y);
                if(c%d!=0) { printf("-1
    "); Flag=true;}
                x=((c/d*x)%(b/d)+b/d)%(b/d);//最小正单元
                c1=a*x+c1;a=a*b/d;
            }   
            if(!Flag) printf("%lld
    ",c1);
            //yes
        }   return 0;
    }
    View Code

    【C】polya(记住加逆元!!!)

    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    using namespace std;
    const int Mod=1000000007;
    #define ll long long
    ll gcd(ll a,ll b) {  if(b==0) return a;  return gcd(b,a%b); }
    ll qpow(ll a,ll x)
    {
        ll res=1;a%=Mod;
        while(x){
            if(x&1LL) res=res*a%Mod;
            x>>=1LL;
            a=a*a%Mod;
        } return res;
    }
    int main()
    {
        ll T,ans,n,m,i,Case=0;
        scanf("%lld",&T);  while(T--){
            scanf("%lld%lld",&m,&n);
            ans=0;
            for(i=0;i<n;i++) ans=(ans+qpow(m,gcd(n,i)))%Mod;
            if(n&1)  ans=(ans+n*qpow(m,n/2+1))%Mod;  
            else {  
                ans=(ans+n/2*qpow(m,n/2))%Mod;
                ans=(ans+n/2*qpow(m,n/2+1))%Mod;  
            }  
               ans=ans%Mod*qpow(2*n,Mod-2)%Mod;
            printf("Case #%lld: %lld
    ",++Case,ans);
        }   
        return 0;
    }
    View Code

    【D】博弈:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <stack>
    #include <queue>
    #include <map>
    #include <set>
    #include <vector>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    int main()
    {
        int T,n,k=2,cas=1;
        while(~scanf("%d",&n))
        {   
            if(n%2==1&&k==1) cout<<"XiaoNiu"<<endl;
            else if(k>=n) cout<<"XiaoNiu"<<endl;
            else cout<<"XiaoKe"<<endl;
        }
        return 0;
    }
    View Code

    【E】高精度

    #include<stdio.h>
    int a[10005];
    int main()
    {
        int n;
     
        while(scanf("%d",&n)!=EOF)
            {
                int index,temp,i,j;
                a[0]=1;
                index=0;
                for(i=1;i<=n;i++)
                {
                    temp=0;
                    for(j=0;j<=index;j++)
                    {
                        a[j]=a[j]*i+temp;
                        temp=a[j]/10000;
                        a[j]%=10000;
                    }
     
                    if(temp>0)
                    {
                    a[++index]=temp;
                    }
                }
                printf("%d",a[index]);
                for(i=index-1;i>=0;i--)
                {
                    if(a[i]>=1000)
                    printf("%d",a[i]);
                    else if(a[i]>=100)
                    printf("0%d",a[i]);
                    else if(a[i]>=10)
                    printf("00%d",a[i]);
                    else
                         printf("000%d",a[i]);
                }
                  printf("
    ");
            }
        return 0;
    }
    View Code

    【F】数据有问题。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn=1e3+10;
    int vis[maxn];
    int main()
    {
          int n;
        while(~scanf("%d",&n))
        {
            if(n==0)
                break;
                int t;
            for(int i=0;i<n;i++)
            {
                scanf("%d",&t);
                vis[t]++;
            }
            int flag=0;
            for(int i=0;i<101;i++)
            {
                if(vis[i]%2==1)
                {
                      flag=1;
                      break;
                }
            }
            if(flag)
                printf("Win
    ");
            else
                printf("Lose
    ");
                memset(vis,0,sizeof(vis));
     
        }
        return 0;
    }
    View Code

    【G】容斥定理

    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    long long qpow(int a,int x)
    {
        long long res=1;
        while(x){
            if(x&1) res*=a;
            a=a*a;
            x>>=1;
        } return res;
    }
    int main()
    {
        long long n,ans,tmp;
        int a,b,c,d,i,j,k,x;
        while(~scanf("%lld",&n)){
            ans=0;
            ans+=n/2;
            ans+=n/5;
            ans+=n/11;
            ans+=n/13;
            ans-=n/(2*5);
            ans-=n/(2*11);
            ans-=n/(2*13);
            ans-=n/(5*11);
            ans-=n/(5*13);
            ans-=n/(11*13);
            ans+=n/(2*5*11);
            ans+=n/(2*11*13);
            ans+=n/(5*11*13);
            ans+=n/(2*5*13);
            ans-=n/(2*5*11*13);
            printf("%lld
    ",n-ans);
            //yes
        } return 0;
    }
    View Code

    【H】不会

    【I】皮克+GCD

    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define ll long long
    ll x[4],y[4],ans[4];
    double S;
    ll gcd(ll a,ll b) 
    { 
        return b== 0 ? a : gcd(b,a%b); 
    } 
       
    void getS()
    {
        ll x1=x[2]-x[1];
        ll y1=y[2]-y[1];
        ll x2=x[3]-x[1];
        ll y2=y[3]-y[1];
        S=abs(1.0*x1*y2-x2*y1)/2;
    }
    void get(int u)
    {
        int x0,y0;
        if(u==1){
            x0=abs(x[2]-x[1]);
            y0=abs(y[2]-y[1]);
        }
        if(u==2){
            x0=abs(x[3]-x[2]);
            y0=abs(y[3]-y[2]);
        }
        if(u==3){
            x0=abs(x[3]-x[1]);
            y0=abs(y[3]-y[1]);
        }
        if(x0==0&&y0==0) ans[u]=1;
        ans[u]=gcd(x0,y0)-1;
    }
    int main()
    {
        while(~scanf("%lld",&x[1])){
            if(x[1]==-1) break;
            scanf("%lld%lld%lld%lld%lld",&y[1],&x[2],&y[2],&x[3],&y[3]);
            getS();
            get(1);
            get(2);
            get(3);
            int tS=S;
            ans[0]=S-(ans[1]+ans[2]+ans[3]+3)/2+1;
            printf("%.1f %lld %lld %lld %lld
    ",S,ans[0],ans[1],ans[2],ans[3]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    LeetCode:删除链表中的节点【203】
    精益创业和画布实战(1):变革家,让天下没有难懂的生意
    怎么投资理财,如果有且仅有100万本金?
    怎么投资理财,如果有且仅有100万本金?
    Java集合——HashMap、HashTable以及ConCurrentHashMap异同比较
    View绘制详解,从LayoutInflater谈起
    Java线程和多线程(七)——ThreadLocal
    跳槽谋发展:人生发展的一些思考和最近找工作的坎坷经历
    跳槽谋发展:人生发展的一些思考和最近找工作的坎坷经历
    三个案例带你看懂LayoutInflater中inflate方法两个参数和三个参数的区别
  • 原文地址:https://www.cnblogs.com/hua-dong/p/8414090.html
Copyright © 2020-2023  润新知