acm新生赛第一场

来源:互联网 发布:中兴手机在线升级软件 编辑:程序博客网 时间:2024/04/27 22:52

真正开始我的acm生涯了,第一场新生赛6道题,经过六小时的奋斗,也就码出来2道题,还真是新生啊,但不论做出几道,应该更加努力,总结完善。

 

A.Eming

Eming is a contest hold by WHUACM training team. The aim is to select new members of the team. 

Usually, the first problem is a very simple problem such as “a+b problem”. But this time, Xioumu is tired of this kind of problem, he decide to solve “a and b problem”.

Give you the result of a + b and a^2 – b^2, please output the result of a and b.

Input

There are several test cases. For each case there are two double numbers indicating a+b and a^2-b^2. You may assume that a+b will not be zero.

Output

For each case please output the result of a and b in one line, rounded to 2 decimal places.

Sample Input

3 -3

Sample Output

1.00 2.00

A题应该来说比较简单,列式解答二元二次方程组就行了,但是在码代码的时候开始用c捞出错误,最后改成c++就正确,最后才发现,是变量的数据类型错了,double型的变量输入时scanf("%Lf %Lf",&c,&d),是lf,在用c++是程序直接定义不用自己写,但c++耗时比c长,所以应尽量用c,代码如下

#include<stdio.h>
main()
{
double a,b,c,d;
while(scanf("%Lf %Lf",&c,&d)!=EOF)
{
a=(d/c+c)/2;
b=c-a;
printf("%.2f %.2f\n",a,b);
}
}


B.ArithmetiProgression

“In mathematics, an arithmetic progression (AP) or arithmetic sequence is a sequence of numbers such that the difference between the consecutive terms is constant. For instance, the sequence 5, 7, 9, 11, 13, … is an arithmetic progression with common difference of 2.”

Wikipedia

This is a quite simple problem, give you the sequence, you are supposed to find the length of the longest consecutive subsequence which is an arithmetic progression.

Input

There are several test cases. For each case there are two lines. The first line contains an integer number N (1 <= N <= 100000) indicating the number of the sequence. The following line describes the N integer numbers indicating the sequence, each number will fit in a 32bit signed integer.

Output

For each case, please output the answer in one line.

Sample Input

6

1 4 7 9 11 14

Sample Output

3


B题也比较简单,求出一组数中最长等差数列的长度,主要的麻烦就是这组数中可能有很多个等差数列,所以我用一个数组

j[m]来记录每个等差数列的长度,之后求出数组j中的最大值输出就行了,但是我有个疑问,若输入1个数怎么办,长度为1吗?我的代码开始给数组j赋值都是2,所以最小的也是2,没有1,但是让我过了,不知道为什么。我又改了该代码,把1加进去了,代码如下

#include<stdio.h>
#define m 100000
main()
{
int n,a[m],i,j[m],k,l;
        while(scanf("%d",&n)!=EOF)
{
                            
   for(i=0;i<n;i++)
  scanf("%d",&a[i]);


for(i=0;i<n;i++)
j[i]=2;
k=0;
l=0;
        for(i=0;i<n-2;i++)
{
if(k==0)
{
if((a[i]-a[i+1])==(a[i+1]-a[i+2]))
{
k=1;
l++;
j[l]+=1;
}
}
                else
                       if((a[i]-a[i+1])==(a[i+1]-a[i+2]))
                               j[l]+=1;
     else
 k=0;
}
for(i=1;i<n;i++)
if(j[0]<j[i])
j[0]=j[i];
   if(n==1)
                       printf("1\n");  
            else
                       printf("%d\n",j[0]);
}
}



C.An Easy Puz

Wddpdh find an interesting mini-game in the BBS of WHU, called “An easy PUZ”. It’s a 6 * 6 chess board and each cell has a number in the range of 0 and 3(it can be 0, 1, 2 or 3). Each time you can choose a number A(i, j) in i-th row and j-th column, then the number A(i, j) and the numbers around it (A(i-1, j), A(i+1, j),A(i, j-1),A(i, j+1), sometimes there may just be 2 or 3 numbers.) will minus 1 (3 to 2, 2 to 1, 1 to 0, 0 to 3). You can do it finite times. The goal is to make all numbers become 0. Wddpdh now come up with an extended problem about it. He will give you a number N (3 <= N <= 6) indicate the size of the board. You should tell him the minimum steps to reach the goal.

Input

The input consists of multiple test cases. For each test case, it contains a positive integer N(3 <= n <= 6). N lines follow, each line contains N columns indicating the each number in the chess board.

Output

For each test case, output minimum steps to reach the goal. If you can’t reach the goal, output -1 instead.

Sample Input

3

1 1 0

1 0 1

0 1 1

3

2 3 1

2 2 1

0 1 0

Sample Output

2

3


C题我是真不会,看完源代码,也不是很清楚,大致过程了解,但不会编,下面是代码

#include <cstdio>
#include <cstring>
const int d[8]={0,1,4,16,64,256,1024,4096};
int n,a[9][9],f[9][9];
bool yes()
{
    for (int i(1);i<=n;i++)
{
        if (f[n+1][i]>0) 
return false;
    }
    return true;
}
int main()
{
    while (scanf("%d",&n)!=EOF)
{
        int ans=10000;
        memset(a,0,sizeof(a));
        for (int i(1);i<=n;i++)
{
            for (int j(1);j<=n;j++)
{
                scanf("%d",&a[i][j]);
            }
        }
        for (int K(0);K<d[n+1];K++)
{
            memset(f,0,sizeof(f));
            f[1][1]=K%4;
            for (int i(2);i<=n;i++) 
f[1][i]=(K%d[i+1])/d[i];
            for (int k(2);k<=n+1;k++)
{
                for (int j(1);j<=n;j++)
{
                    int as=a[k-1][j]-f[k-1][j-1]-f[k-1][j]-f[k-1][j+1]-f[k-2][j];
                    while(as<0) as+=4;
                    f[k][j]=as;
}
            }
            if (yes())
{
                int sum=0;
                for (int i(1);i<=n;i++) 
{
                    for (int j(1);j<=n;j++)
{
                        sum+=f[i][j];
                    }
                }
                if (sum<ans) ans=sum;
            }
        }
        if(ans==10000) ans=-1;
        printf("%d\n",ans);
    }
    return 0;
}


D.Brackets 

This year MK is 5 years old. So he decides to learn some arithmetic. But he was confused by how to write the brackets. He has already known that the brackets should match when writing them correctly. Such as “()(())” is correct but “())(” is not.

The problem is that, if there are N pairs of brackets, how many ways that MK can write them correctly?           

Input 

   There are several test cases. Each case contains a number N (1 <= N <= 1000) indicating the pairs of brackets.

Output 

For each case, please output the answer mod 1,000,000,007.

Sample Input 

5

7

Sample Output 

42

429


D题一学长提醒是catalan数,我就百度了一下,

h0=1h(1)=1,catalan数满足递归式:

h(n)=h(0)*h(n-1)+h(1)*h(n-2)+……+h(n-1)*h(0)   其中n>=2

简化递推关系为:h(n)=(4n-2)/(n+1)*h(n-1)    n>1 h(0)=1,

知道这个递推公式就简单了,但开始我是真不知道怎么做,看似是一个排序有多少种,但感觉有很多,很麻烦,看看前几项的数就知道了

卡塔兰数例的前几项为

1,1,2,5,14,42,132,429,1430,4862,16796,58786,208012,742900,2674440,9694845,35357670

129644790,477638700,1767263190,6564120420,24466267020,91482563640,343059613650

1289904147324,4861946401452,……

很大很大,所以定义的时候,数据类型应定义为long long型的,代码如下

#include<stdio.h>
#define m 1000
main()
{
long long k[m];
int i,j,n;
k[0]=1;k[1]=1;
    for(i=2;i<=1000;i++)
{
   k[i]=0;
   for(j=0;j<i;j++)
       k[i]=(k[i]+(k[j]*k[i-1-j])%1000000007)%1000000007;
    }
while(scanf("%d",&n)!=EOF)
{    
printf("%d\n",k[n]%1000000007);
}
}



E.Function

Define a function f(n)=(f(n-1)+1)/f(n-2). You already got f(1) and f(2). Now, give you a number m, please find the value of f(m).

Input

There are several test cases. Each case contains three integers indicating f(1), f(2) and m ( 1 <= f(1), f(2), m <= 1000,000,000).

Output

For each case, please output the value of f(m), rounded to 6 decimal places.

Sample Input

1 1 3

Sample Output

2000000


E题开始看的时候,感觉应该用快速幂的方法,但后来发现,不论f1,f2为何值,他们都是循环的,而且是5个一循环,只是开始我纳闷为什么输入的时候要输入整型的f1,f2,m,那到后面算的时候不是成整除的吗,出现0就不知道怎么做了,而结果要保留6为小数,应该不是整除,所以将数组定义成double型的,最后用m除以5取余就行了,代码如下

#include<stdio.h>
main()
{
int i,j,m,f1,f2;
double a[5];
while(scanf("%d %d %d",&f1,&f2,&m)!=EOF)
{
a[0]=f1;
a[1]=f2;
        for(i=2;i<5;i++)
{
a[i]=(a[i-1]+1)/a[i-2];
}
        j=m%5;
if(j==0)
printf("%.4f\n",a[4]);
else
            printf("%.4f\n",a[j-1]);
}
}



F.Triangle

It is a simple task, for N points on the 2D plane, you are supposed to find whether there are three points which could form a isosceles triangle.

Input

There are several test cases. For each case, the first line is an integer N (3 <= N <= 500) indicating the number of points. N lines follow, each line contains two doubles(not exceed 1000.0), indicating the coordinates of the points.

Output

For each case, if there exists a solution which could form a isosceles triangle, output “YES”, else output “NO”.

Sample Input

3

0 0

1 1

-1 1

3

0 0

1 1

5 10

Sample Output

YES
NO



F题是求是否可以构成等腰三角形,500个点要一个一个遍历,应该先确定一个点,求出这个点到其他点的长度,看是否构成等腰三角形,之后选第二个点,依次类推,但肯定会超时,求大神指导,有没有简单的方法。


总结:做题时尽量用c,能用算法的尽量用算法,尽量不超时,做题时先要弄清题意,耐心分析,先模拟,多测几组数据,寻找规律。


原创粉丝点击