方陣旋轉—取球概率—巧開平方
①方陣旋轉
對一個方陣轉置,就是把原來的行號變列號,原來的列號變行號
例如,如下的方陣:
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
- 藍橋杯-代碼填空之一
- 藍橋杯-代碼填空之二
- 藍橋杯-代碼填空之三
- 藍橋杯-代碼填空之精品
- 藍橋杯-歷屆試題之翻硬幣
- 藍橋杯-代碼填空之四
- 藍橋杯-結果填空題
- 藍橋杯-結果填空之排座位
- 藍橋杯-歷屆試題之大臣的旅費