X-man

导航

计算机学院2014年“新生杯”ACM程序设计大赛

1440: 棋盘摆车问题

对于输入n,k;

1.当n<k时,无满足的摆法

2.否则

第一个车可以排n*n个位置(即整个棋盘),第二个可排(n-1)*(n-1)个位置,……

正如排列组合一样,车与车之间没有区别(这是组合问题),于是要除以k!

#include<stdio.h>

long long A(int x)

{

    long long num=1;

    for(int i=2;i<=x;i++)

    {

        num*=i;

    }

    return num;

}

int main()

{

    int n,k;

    long long ans;

    while(scanf("%d %d",&n,&k)!=EOF)

    {

        ans=1;

        if(n<k)

        {

            printf("0\n");

            continue;

        }

        for(int i=n,j=1; j<=k; i--,j++)

        {

            ans*=i*i;

        }

        ans/=A(k);

        printf("%lld\n",ans);

    }

    return 0;

}

1441: N!

提示很明显m=N!

log10(m)=log10(N)*log10(N-1)……log10(2)

#include<stdio.h>

#include<math.h>

int main()

{

    int n;

    double ans;

    int Case=0;

    while(scanf("%d",&n)!=EOF)

    {

        ans=0;

        if(n>=1)

        {

            for(int i=2;i<=n;i++)

                ans+=log10(i);

        }

        ans+=1;

        int ans1=(int)ans;

        printf("Case %dth is : %d.\n",++Case,ans1);

       //printf("Case %dth is : %d %f %.0f.\n",++Case,ans1,ans,ans);试一试用这行输出,或许会发现错的缘由

    }

    return 0;

}

 

 

 

1442: 决胜千里之外

Nim博弈问题

博弈基本原理:

先手必胜当且仅当:
    (1)所有堆的石子数都为 1 且游戏的 SG 值为 0
    (2)有些堆的石子数大于 1 且游戏的 SG 值不为 0

http://www.cnblogs.com/XDJjy/p/3352161.html

#include<stdio.h>

int main()

{

    int n,m;

    while(scanf("%d %d",&n,&m)!=EOF)

    {

        if(n%(m+1))printf("胡爷真男人\n");

        else printf("雷神真男人\n");

    }

    return 0;

}

 

1443: 无限的路

我的思路:

分析图形特点,线段被分为两类,一类的单位长度为

另一类为

1.对于输入的两个点,先转换到y坐标轴上,

这样方便计算第二类距离

2.然后计算第一类的线段长度,

#include<stdio.h>

#include<math.h>

double line[210];

void Line()

{

    for(int i=1;i<210;i++)

        line[i]=sqrt((double)i*i+(i-1)*(i-1));

}

int main()

{

    int n;

    scanf("%d",&n);

    int x1,y1,x2,y2;

    Line();

    while(n--)

    {

        scanf("%d %d %d %d",&x1,&y1,&x2,&y2);

        int sum1=x1+y1;

        int sum2=x2+y2;

        int sum,x;

        if(sum1>sum2)

        {

            sum=sum1;

            sum1=sum2;

            sum2=sum;//sum2为较大者

 

            x=x1;

            x1=x2;

            x2=x;

        }

        double ans=0;

        for(int i=sum1+1; i<=sum2; i++)

        {

            ans+=line[i];

        }

        //printf("&%lf %d %d\n",ans,sum1,sum2);

        ans-=sqrt(2.0)*x1;

        ans+=sqrt(2.0)*x2;

        for(int i=sum1; i<sum2; i++)

            ans+=sqrt(2.0)*i;

        printf("%.3lf\n",ans);

    }

    return 0;

}

 

1444: 判断素数

基本的判断素数的方法如本程序

还有更多时间更优的算法。

#include<stdio.h>

#include<math.h>

int Judge(int m)

{

    for(int i=2; i<=sqrt(m)+0.5; i++)//若写成I<m,则会超时

    {

        if(m%i==0)return 0;

    }

    return 1;

}

int main()

{

    int n,m;

    scanf("%d",&n);

    while(n--)

    {

        scanf("%d",&m);

        if(Judge(m))printf("Yes\n");

        else printf("No\n");

    }

    return 0;

}

1448: 等式

本题是一道杂题,也是防AK(all killed即全部被解决)的题目,

将n移到右边得等式:x^2+s(x,m)x=n

发现左边两项均为正数,得到x< ,

只需向前尝试( -1000, )区间的解。(无完整证明)

#include<stdio.h>

#include<math.h>

int S(int x,int m)

{

    int num=0;;

    while(x>0)

    {

        num+=x%m;

        x/=m;

    }

    return num;

}

int main()

{

    int Case;

    long long n;

    int m;

    scanf("%d",&Case);

    while(Case--)

    {

        scanf("%lld %d",&n,&m);

        int st=sqrt(n);

        int count=1;

        int ans=-1;

        for(int i=st; i>0&&count<1000; i--,count++)

        {

            if((long long)i*i+(long long)S(i,m)*i==n)ans=i;

        }

        printf("%d\n",ans);

    }

}

1452: 青蛙的故事

递推公式的推导

假设青蛙在k(k>2)阶上

则青蛙必定是从k-1阶跳一步上来

或是从k-2阶跳两步上来

得递推公式f[k] = f[k-1]+f[k-2]

f[1]=1;

f[2]=2;

代码1:(超时)

#include<stdio.h>

int Func(int m)

{

    if(m==1)return 1;

    else if(m==2)return 2;

    else return Func(m-2)+Func(m-1);}

int main()

{

    int n;

    while(scanf("%d",&n)!=EOF)

    {

        printf("%d\n",Func(n));

    }

    return 0;

}

代码2;

#include<stdio.h>

int f[50];

int Init()

{

    f[1]=1;

    f[2]=2;

    for(int i=3;i<40;i++)

    {

        f[i]=f[i-1]+f[i-2];

    }

}

int main()

{

    int n;

    Init();

    while(scanf("%d",&n)!=EOF)

    {

        printf("%d\n",f[n]);

    }

    return 0;

}

1453: 数字游戏

没有设严格的时间限制,

只需先找到k在哪一行

然后确定k是本行的第几个

#include<stdio.h>

#include<string.h>

int main()

{

    int _case;

    int n,m;

    long long k;

 

    //scanf("%d",&_case);_case--

    while(scanf("%d %d %lld",&n,&m,&k)!=EOF)

    {

        int t;

        long long sum=0;

        //k=p;

        for(t=n;t>=0;t-=m)

        {

            sum+=t;

            if(k-sum<=0)break;

        }

        //printf("%d %d\n",sum,t);

        if(t>=0)printf("%lld\n",n-(sum-k));

        else printf("0\n");

    }

    return 0;

}

 

1454: 偶数拆分

代码1也不会超时,即大多数的题目并没有严格卡时间

只要思路对,代码敲对即可

代码1:

#include<stdio.h>

#include<math.h>

#include<string.h>

const int Max=10010;

int prime[Max];

//int counter=0;

int Judge(int x)

{

    for(int i=2; i<=sqrt(x)+0.5; i++)

    {

        if(x%i==0)return 0;

    }

    return 1;

}

int main()

{

    //Pri();

    //for(int i=0;i<10010;i++)

        //if(prime[i])printf("%d ",i);

    int n,ans;

    while(scanf("%d",&n)!=EOF)

    {

        if(!n)break;

        ans=0;

        for(int i=2;i<n/2;i++)

        {

            if(Judge(i)&&Judge(n-i))

            {

                //printf("%d %d\n",i,n-i);

                ans++;

            }

        }

        printf("%d\n",ans);

    }

    return 0;

}

代码2:

#include<stdio.h>

#include<math.h>

#include<string.h>

const int Max=10010;

int prime[Max];

//int counter=0;

int Pri()

{

    memset(prime,0,sizeof(prime));

    for(int i=2; i<Max; i++)

    {

        int flag=1;

        for(int j=2;j<=sqrt(i)+0.5;j++)

        {

            if(i%j==0)

            {

                flag=0;

                break;

            }

        }

        if(flag)prime[i]=1;

    }

}

int main()

{

    Pri();

    //for(int i=0;i<10010;i++)

        //if(prime[i])printf("%d ",i);

    int n,ans;

    while(scanf("%d",&n)!=EOF)

    {

        if(!n)break;

        ans=0;

        for(int i=2;i<n/2;i++)

        {

            if(prime[i]&&prime[n-i])

            {

                //printf("%d %d\n",i,n-i);

                ans++;

            }

        }

        printf("%d\n",ans);

    }

    return 0;

}

 

小结:

         本次比赛完满结束,先感谢一下出题者。虽然这些题是他们眼里的水题,但是出题者也是煞费苦心,正如以前的学长一样。然后是尽职尽责的团学年工作者,当然也不能忘了默默支持大家的领导老师。

         希望大家

            阅读,思考,分享,K题。编程优化人生!

 

 

 

 

 

                                                                                    Xdj

posted on 2014-03-25 19:30  雨钝风轻  阅读(298)  评论(0编辑  收藏  举报