acmer之路(2)三月第四周日志
这周比较繁忙,周一到周四课比较多,周五为了准备中科院软件园的一个面试早上五点多就起床赶公交,周天又参加了院里的一场足球赛。在这周里,我一共只写了十道题,现在贴出来和大家分享一下。
三月第四周.png
ID 2004
#include<stdio.h>
int main()
{
int grade;
while (scanf("%d", &grade) != EOF)
{
if (grade < 0 || grade>100)
{
printf("Score is error!\n");
}
else
{
grade = grade / 10;
switch (grade)
{
case 10:
case 9: printf("A\n"); break;
case 8: printf("B\n"); break;
case 7: printf("C\n"); break;
case 6: printf("D\n"); break;
default: printf("E\n"); break;
}
}
}
return 0;
}
这一题很简单,不过初学者容易忘记switch语句的规范。switch括号里面的数据类型和case后面的数据类型一定要对应。
ID 2005
#include<stdio.h>
int main() {
int a, b, c;
int day;
day = 0;
int i,j;
int d[13] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int k[13] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
while (~scanf("%d/%d/%d", &a, &b, &c))
{
if (a % 400 == 0 || (a % 4 == 0 && a % 100 != 0))
{
if (b == 1)
{
printf("%d\n", c);
}
else
{
for (i = 0; i <= (b - 1); i++)
{
if(i == b - 1)
{
day = day + c;
printf("%d\n", day); break;
}
day = day + k[i];
}
day = 0;
}
}
else
{
if (b == 1)
{
printf("%d\n", c);
}
else
{
for (j = 0; j <= (b - 1); j++)
{
if (j == b - 1)
{
day = day + c;
printf("%d\n", day); break;
}
day = day + d[j];
}
day = 0;
}
}
}
return 0;
}
这一题我当时是提交了好几遍才AC的,而且个人认为我的逻辑有些繁杂。因为闰年与平年的二月天数有区别,我单独设置了两个数组分别来存放闰年与平年。先判断是不是闰年,是就用第一个数组来累加,否就用第二数组来累加。很明显,我第二个数组的设置是多余的,后来看了网上很多人的实现更觉得是个累赘。当时为了图懒省事,索性一刀切弄了两个数组。
ID 2006
#include<stdio.h>
int main()
{
int n;
int i;
int a[50];
int product;
product = 1;
while (scanf("%d", &n) != EOF)
{
for (i = 0; i < n; i++)
{
scanf("%d", &a[i]);
if (a[i] % 2 != 0)
{
product = product * a[i];
}
}
printf("%d\n", product);
product = 1;
}
return 0;
}
ID 2007
#include<stdio.h>
int main()
{
int a, b;
int i, j;
int product1, product2;
product1 = 0;
product2 = 0;
int temp;
while (scanf("%d %d", &a, &b) != EOF)
{
if (a > b)
{
temp = a;
a = b;
b = temp;
}
for (i = a; i <= b; i++)
{
if (i % 2 == 0)
{
product1 = product1 + i * i;
}
}
for (j = a; j <= b; j++)
{
if (j % 2 != 0)
{
product2 = product2 + j * j*j;
}
}
printf("%d %d\n", product1, product2);
product1 = 0;
product2 = 0;
}
return 0;
}
这题有两个地方需要注意。其一要判断输入的两个值的大小关系,这个我一开始忽略了怎么都不通过。其二要注意输出的乘积在最后的置零,值的累积会让后面的输出都错误。
ID 2018
#include<stdio.h>
int main()
{
int n;
int count;
int temp;
int age[4] = { 0, 0, 0, 0 };
int i;
while (scanf("%d", &n),n)
{
if (n == 1)
{
age[3] = 1;
printf("%d\n", age[3]);
}
else
{
age[3] = 1;
age[2] = age[1] = 0;
for (i = 2; i <= n; i++)
{
temp = age[1];
age[1] = age[3];
age[3] = age[3] + age[2];
age[2] = temp;
}
count = age[1] + age[2] + age[3];
printf("%d\n", count);
}
}
return 0;
}
这题是很有意思的,其实就是斐波那契数列的变形。首先用递归的方法肯定不行。那么我们换一种思路,把母牛分为三种,一种是可生育的放置在age[3]里面,一种是两岁的放在age[2]里面,还有一个就是放在age[1]。然后他们三个有什么关系呢?很明显,每一年过去,一岁牛变成两岁牛,两岁牛变成可生育牛,而可生育牛的数量也是下一年一岁牛的数量。
ID 2013
#include<stdio.h>
int main()
{
int n;
int i;
int total;
while (scanf("%d", &n) != EOF)
{
total = 1;
for (i = n; i > 1; i--)
{
total = 2 * (total + 1);
}
printf("%d\n", total);
}
return 0;
非常简单的数学游戏。
ID 2012
#include<stdio.h>
#include<math.h>
int main()
{
int x, y, n, k, i, j;
while (scanf("%d%d", &x, &y) != EOF)
{
if (x == 0 && y == 0)
break;
else
{
for (i = x, k = 1; i <= y; i++)
{
n = i * i + i + 41;
for (j = 2; j<sqrt((double)n); j++)
{
if (n%j == 0)
{
k = 0;
break;
}
}
if (k == 0)
{
printf("Sorry\n");
break;
}
}
if (k)printf("OK\n");
}
}
return 0;
}
通过这题给大家一个建议,我们研究算法有时候也要去了解它背后的数学知识。比如素数判断,为何程序里写着判定区间是[2, sqrt(n)]呢?是这样的,如果一个数不是素数,那么肯定可以被除了1与它自身的数整除,也就是说一定有两个数在区间[2,n-1]之间,可以相乘得到n。这两个数肯定有一个数小于sqrt(n)。因此,以上。
ID 2010
#include<stdio.h>
#include<math.h>
int main()
{
int m, n;
int i,j;
int temp;
int num[3];
int count;
count = 0;
int a[1000];
while (scanf("%d %d", &m, &n) != EOF)
{
if (m > n)
{
temp = m;
m = n;
n = temp;
}
num[0] = num[1] = num[2] = 0;
for (i = m; i <= n; i++)
{
num[2] = i / 100;
num[1] = (i % 100)/10;
num[0] = (i % 100) % 10;
if (i == (num[0] * num[0] * num[0] + num[1] * num[1] * num[1] + num[2] * num[2] * num[2]))
{
count += 1;
a[count] = i;
}
}
if (count > 0)
{
for (j = 1; j <= count; j++)
{
printf("%d", a[j]);
if (j != count)
{
printf(" ");
}
else
{
printf("\n");
}
}
}
if (count == 0)
{
printf("no\n");
}
count = 0;
}
return 0;
}
额,这题当时我记得还是遇到点挫折的,可惜记不清了。。。
ID 2009
#include<stdio.h>
#include<math.h>
int main()
{
double n, m;
double sum;
int i;
double temp;
while (scanf("%lf %lf", &n, &m) != EOF)
{
sum = 0;
for (i = 0; i < m; i++)
{
temp = n;
sum = sum + temp;
n = sqrt(n);
}
printf("%.2lf\n", sum);
}
return 0;
}
这题我处理的还是比较巧妙的。用一个中间变量temp储存数列下一个元素的值。
ID 2011
#include<stdio.h>
#include<math.h>
int main()
{
int n;
int i;
int j;
double sum;
double num;
int a[1000];
while (scanf("%d", &n) != EOF)
{
for (i = 0; i < n; i++)
{
scanf("%d", &a[i]);
}
for (i = 0; i < n; i++)
{
num = 1.00;
sum = 0;
for (j = 0; j < a[i]; j++)
{
if (j % 2 == 0)
{
num = 1.00 / (num + j);
}
else
{
num = -(1.00 / (num + j));
}
sum = sum + num;
num = 1.00;
}
printf("%0.2lf\n", sum);
}
}
return 0;
}
这一题处理的也挺巧妙,精华在于num = 1.00 / (num + j)。还有要注意的一点是,我一开始提交总说我格式错误。最后百度才知道,要printf("%0.2lf\n", sum)这么写才行,少那个0会报错。