方阵旋转—取球概率—巧开平方
①方阵旋转
对一个方阵转置,就是把原来的行号变列号,原来的列号变行号
例如,如下的方阵:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
转置后变为:
1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
但,如果是对该方阵顺时针旋转(不是转置),却是如下结果:
13 9 5 1
14 10 6 2
15 11 7 3
16 12 8 4
下面的代码实现的功能就是要把一个方阵顺时针旋转。
~~~
void rotate(int* x, int rank)
{
int* y = (int*)malloc(___________________); // 填空
for(int i=0; i<rank * rank; i++)
{
y[_________________________] = x[i]; // 填空
}
for(i=0; i<rank*rank; i++)
{
x[i] = y[i];
}
free(y);
}
int main(int argc, char* argv[])
{
int x[4][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
int rank = 4;
rotate(&x[0][0], rank);
for(int i=0; i<rank; i++)
{
for(int j=0; j<rank; j++)
{
printf("%4d", x[i][j]);
}
printf("\n");
}
return 0;
}
~~~
这道题就是矩阵转置,只不过是顺时针的,看一遍代码,第二个for循环将x[i]=y[i] 然后把y给free掉,y肯定是中间变量,用来存正确的放置方法的,所以它的大小应该等同于X的大小。
那么第一个空肯定就是rank*rank呗,如果这样写提交,肯定一个大红叉叉在上面。Why?因为你开辟的空间,确定是
rank*rank吗?你心里把它默认为Int形式,可是代码不知道啊!所以还需要再乘一个4,作为int型的大小。如果更保险一些,你可以写成 sizeof(int)。
这个如果自己编一个程序没有乘4或者sizeof(int),程序会给你报错的。(PS:malloc 需要头文件 malloc.h)
然后第二个空,开始我还纳闷他是怎么用一个i来进行二维数组的赋值?后来经好友提醒,顿时恍悟:
二维数组可以写成这样:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
5可以用 1,0,同样也可以用长度 1*4+1啊。
所以懂了吧?就是一行的宽度有限个,当你输入的宽度大于该行的宽度,它会给你换下一行,继续找。
答案:
sizeof(int) * rank * rank 或者 4 * rank * rank
(i%rank)*rank+(rank-(i/rank)-1)
②取球概率
口袋中有5只红球,4只白球。随机从口袋中取出3个球,则取出1个红球2个白球的概率是多大?
类似这样的数学问题,在计算的时候往往十分复杂。但如果通过计算机模拟这个过程,比如进行100000次取球模拟,统计一下指定情况出现的次数对计算机来说是方便且快速的。
~~~
srand( (unsigned)time( NULL ) );
int n = 0;
for(int i=0; i<100000; i++)
{
char x[] = {1, 1, 1, 1, 1, 2, 2, 2, 2};
int a = 0; // 取到的红球的数目
int b = 0; // 取到的白球的数目
for(int j=0; j<3; j++)
{
int k = rand() % (9-j);
if(x[k]==1)
a++;
else
b++;
_______________________;
}
if(a==1 && b==2) n++;
}
printf("概率=%f\n", n/100000.0*100);
~~~
题目很简单就是模拟取球,空格上填的第一遍看也能懂,就是怕取道的那个下标的球去掉,但怎么去除?
赋0?赋0的话下次碰到会以else 让b++,显然不可以。
其实,题目中已经给了你隐藏的信息,题中每次rand()值对9-j取模而不是9,也就是说,第一次对9取余,
第二次对8取余,第三次对7取余,这样第一次所有球都是好球,第二次,最后一个球是费球,用不到,
第三次最后两个都是废球,也用不到。如此一来,我们完全可以把取到的球和最后的互换,这样取到的球,
可以扔到后面做废球,而后面的可以换到前面,继续来随机取球。
答案: x[k] = x[9-j-1]
③开平方
开平方
如果没有计算器,我们如何求2的平方根?
可以先猜测一个数,比如1.5,然后用2除以这个数字。如果我们猜对了,则除法的结果必然与我们猜测的数字相同。我们猜测的越准确,除法的结果与猜测的数字就越接近。
根据这个原理,只要我们每次取猜测数和试除反馈数的中间值作为新的猜测数,肯定更接近答案!这种计算方法叫做“迭代法”。
下面的代码模拟了如何用手工的方法求2的平方根的过程。
~~~
double n = 2;
double a = 0;
double b = n;
while(fabs(a-b)>1E-15)
{
a = (a+b)/2;
b = __________;
}
printf("%f\n", a);
~~~
很短的代码,就是用迭代法求平方根,题目中给出了: 只要我们每次取猜测数和试除反馈数的中间值 作为新的猜测数,肯定接近答案。根据代码,我们也明白,a肯定是猜测数,b肯定是试除反馈数。(为什么?因为a=(a+b)/2,
a是新的猜测数,新猜测数的产生,根据题意就明白了b肯定是试除反馈数),刚开始读题,我始终搞不懂什么叫试
除反馈数,b要怎么求呢?
再仔细看看题目中的描述,b是 试除反馈数,反馈数不就是我们求的猜测数吗,于是乎,答案随之跃出。
答案:n/a
- 前言
- 入门训练四道题
- 基础练习之闰年判断——BASIC-1
- 基础练习之01字串——BASIC-2
- 基础练习之字母图形——BASIC-3
- 基础练习之数列特征——BASIC-4
- 基础练习之查找整除——BASIC-5
- 基础练习之杨辉三角形——BASIC-6
- 基础练习之特殊的数字——BASIC-7
- 基础练习之回文数——BASIC-8
- 基础练习之特殊回文数——BASIC-9
- 基础练习之十进制转十六进制——BASIC-10
- 基础练习之十六进制转十进制——BASIC-11
- 基础练习之十六进制转八进制——BASIC-12
- 基础练习之数列排序——BASIC-13
- 算法训练之区间K大数查询——ALGO-1
- 算法训练之最大最小公倍数——ALGO-2
- 蓝桥杯-代码填空之一
- 蓝桥杯-代码填空之二
- 蓝桥杯-代码填空之三
- 蓝桥杯-代码填空之精品
- 蓝桥杯-历届试题之翻硬币
- 蓝桥杯-代码填空之四
- 蓝桥杯-结果填空题
- 蓝桥杯-结果填空之排座位
- 蓝桥杯-历届试题之大臣的旅费