蓝桥杯-代码填空之二
最后更新于:2022-04-01 14:53:20
干支纪年法—歌赛新规则—红球多于白球的概率—交换变量—考拉兹猜想—利息计算
①干支纪年法
在我国古代和近代,一直采用干支法纪年。它采用10天干和12地支配合,一个循环周期为60年。
10天干是:甲,乙,丙,丁,戊,己,庚,辛,壬,癸
12地支是:子,丑,寅,卯,辰,巳,午,未,申,酉,戌,亥
如果某年是甲子,下一年就是乙丑,再下是丙寅,......癸酉,甲戌,乙亥,丙子,....
总之天干、地址都是循环使用,两两配对。
今年(2012)是壬辰年,1911年辛亥革命
下面的代码根据公历年份输出相应的干支法纪年。已知最近的甲子年是1984年。
~~~
void f(int year)
{
char* x[] = {"甲","乙","丙","丁","戊","己","庚","辛","壬","癸"};
char* y[] = {"子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"};
int n = year - 1984;
while(n<0) n += 60;
printf("%s%s\n", x[_______], y[_______]);
}
int main(int argc, char* argv[])
{
f(1911);
f(1970);
f(2012);
return 0;
}
~~~
这道题,最近的一个甲午年(就是对10或者12取模都为0)是1984年,就以它为标准,求模就可以了,
题目中也有对给出的年份小于1984年的处理(n+=60),这题难度,应该很小了。。。
答案: n%10 n%12
②歌赛新规
歌手大赛的评分规则一般是去掉一个最高分,去掉一个最低分,剩下的分数求平均。当评委较少的时候,如果我们只允许去掉一个分数,该如何设计规则呢?
有人提出:应该去掉与其余的分数平均值相差最远的那个分数。即“最离群”的分数。
以下的程序用于实现这个功能。其中x存放所有评分,n表示数组中元素的个数。函数返回最“离群”的那个分数值。
~~~
double score(double x[], int n)
{
int i,j;
double dif = -1;
double bad;
for(i=0; i<n; i++)
{
double sum = 0;
for(j=0; j<n; j++)
{
if(________) sum += x[j];
}
double t = x[i] - sum / (n-1);
if(t<0) t = -t;
if(t>dif)
{
dif = t;
bad = x[i];
printf("%d, %f\n", i, x[i]);
}
}
return bad;
}
~~~
题目很简单,就是求最离群的数字,如果让我打代码,我猜可能是求最大和最小的,然后剩下的求平均,通过它们之间的差值来查找,这题目的做法,应该是,计算n-1个平均值,来比较,所以两层循环,
第一层,计算2~n的,第二层计算1,3~n。。。。所以if里应该是去除掉当前循环的i,对应的值再求和
答案:i!=j
③概率问题
某个袋子中有红球m个,白球n个。现在要从中取出x个球。那么红球数目多于白球的概率是多少呢?
下面的代码解决了这个问题。其中的y表示红球至少出现的次数。
这与前文的问题是等价的。因为如果取30个球,要求红球数大于白球数,则等价于至少取出16个红球。
~~~
/*
m: 袋中红球的数目
n: 袋中白球的数目
x: 需要取出的数目
y: 红球至少出现的次数
*/
double pro(int m, int n, int x, int y)
{
if(y>x) return 0;
if(y==0) return 1;
if(y>m) return 0;
if(x-n>y) return 1;
double p1 = _______________________;
double p2 = _______________________;
return (double)m/(m+n) * p1 + (double)n/(m+n) * p2;
}
~~~
刚开始,我以为要直接求出来p1,p2,但是后来一想,不对啊,代码填空题,只给了一个函数,没有给主函数那些,肯定是递归了,再加上题目中给了递归终止的条件,所以肯定是递归了。
知道了递归以后就很简单了:模拟拿球情况,要么拿了一个红球,要么拿了一个白球。
答案:pro(m-1,n,x-1,y-1) pro(m,n-1,x-1,y)
④交换变量
如果要把两个整型变量a、b的值交换,一般要采用一个中间变量做过渡,
但也可以在不借助任何其它变量的情况下完成。
a = _________;
b = _________;
a = _________;
这道题目,有很多种解法,我这里就给出两种吧,一个是用位运算— ^
^(异或)是将两边数都转换成2进制,然后异或,
第一种方法:a=a^b,b=a^b,a=a^b
第二种方法就是 a=a+b,b=a-b,a=a-b
⑤考拉兹猜想
“考拉兹猜想”(又称3n+1猜想、角谷猜想、哈塞猜想、乌拉姆猜想或叙拉古猜想) 和“哥德巴赫猜想”一样目前还没有用数学方法证明其完全成立。在1930年,德国汉堡大学的学生考拉兹,曾经研究过这个猜想,因而得名。在1960年,日本人角谷静夫也研究过这个猜想。
该猜想的叙述十分简单:从任何一个正整数n出发,若是偶数就除以2,若是奇数就乘3再加1,如此继续下去,经过有限步骤,总能得到1。例如:
17-52-26-13-40-20-10-5-16-8-4-2-1
该猜想虽然没有完全证明,但用计算机验证有限范围的数字却十分容易。
~~~
for(int n=2; n<=10000; n++)
{
int m = n;
for(;;)
{
if(____________)
m = m / 2;
else
m = m * 3 + 1;
if( m == 1 )
{
printf("%d ok! \n", n);
break;
}
}
};
~~~
这道题,额,看起来很高端大气上档次,猜想也很厉害的样子,但是空就有些。。。
根据题目所给,遇到偶数时 该数除以2,所以答案就是判断m是不是偶数: m%2==0
⑥利息计算
小李年初在银行存款1千元(一年定期)。他计划每年年底取出100元救助失学儿童。
假设银行的存款利率不变,年利率为3%,年底利息自动计入本金。下面的代码计算5年后,该账户上有多少存款。
~~~
double money = 1000;
int n = 5;
int i;
for(i=0; i<n; i++)
{
money = _______________;
money -= 100;
}
printf("%.2f\n", money);
~~~
这道题啊,唉,每年年末,要把本金加上利息都算上再存进去,扣的钱就不需要减了,下面代码帮助你减了。
答案:money=money*1.03