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

放肆的年华 提交于 2020-05-01 04:18:51

 

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

【A 不凡的大夫】

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

方法二:用公式,斯特林公式:   n! \approx \sqrt{2\pi n}\, \left(\frac{n}{e}\right)^{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\n",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\n"); Flag=true;}
            x=((c/d*x)%(b/d)+b/d)%(b/d);//最小正单元
            c1=a*x+c1;a=a*b/d;
        }   
        if(!Flag) printf("%lld\n",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\n",++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("\n");
        }
    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\n");
        else
            printf("Lose\n");
            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",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\n",S,ans[0],ans[1],ans[2],ans[3]);
    }
    return 0;
}
View Code

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!