2019.2.1 自主訓練日誌

      訓練第十二天,先說一下今天解決的問題。

題目描述:
幼兒園裏面的小朋友在玩橡皮泥,每一個小朋友都有一塊橡皮泥。每一塊橡皮泥都是一個長方體塊。從橡皮泥的大小可以看出哪一個小朋友是老大,哪一個小朋友是小弟。擁有橡皮泥體積最大的小朋友總喜歡欺負擁有橡皮泥體積最小的小朋友。
現在給出n個小朋友的橡皮泥,請輸出誰欺負了誰。輸入單組測試數據。第一行有一個整數n(2<=n<=9)。 接下來有n行,每行給出一個小朋友的信息,三個整數和小朋友的名字,前面三個整數表示長方體塊的長寬高。小朋友的名字非空且不超過8個字符。每一個橡皮泥的體積不超過25000立方單位。
輸入
保證只有一個小朋友的橡皮泥的體積是最大的,並且只有一個小朋友的橡皮泥的體積是最小的。
輸出
輸出兩個名字A和B中間用空格分開,表示A欺負了B。
樣例輸入
3
10 10 2 J
5 3 10 W
5 5 10 B
樣例輸出
B W
解題思路:1.輸入一個int型二維數組和一組字符串,2.計算每一行元素的和,存入另外一個數組,3.使用一種排序方式,通過操作腳標同步字符串的變化,4.按要求利用條件語句輸出字符串。
遭遇的問題:如何輸入多組字符串。 解決方案:
char b[10001[10001];
scanf("%s",b[i]);
題目中說明白不會超出8個字符,於是一開始定義數組b的長度位8,但是忽略了"\0",這導致了在解題過程中的困擾,以後要多加註意。
代碼實現如下
#include
#include
using namespace std;
int a[10][3],c[10];
char b[10001][10001];
int main()
{
int n;
cin>>n;
for(int i = 1;i<=n;i++)
{
for(int j = 1;j<=3;j++)
cin>>a[i][j];
c[i] = a[i][1]*a[i][2]a[i][3];
scanf("%s",b[i]);
}
for(int i = 1;i<n;i++)
for(int j = 1;j<=n-i;j++)
if(c[j]>c[j+1])
{
swap(c[j],c[j+1]);
swap(b[j],b[j+1]);
}
cout<<b[1]<<" "<<b[n];
return 0;
}
其餘的題目解題過程中並沒有遇到什麼值得記錄的困難。
另外今天看完了編程珠璣的第二章(除去習題,因爲延伸太多做不出來,而且都是很實際的問題)學到了一個效率很高的排序方法——二分法,之前老師也教授過。使用二分法,關鍵是找到判斷標誌,進而縮短搜索區間。還有一個二分法的應用講解——向量旋轉,例如字符串abcdefgh,長度爲9(從1開始存),在i=3處進行旋轉成defghabc。最簡單直接的思路:首先將x的前i個元素複製到一個臨時數組中,然後將餘下的n-i個元素向左移動i個位置,最後將最初的i個元素從臨時數組中複製到x中餘下的位置。但是,這種辦法使用的i個額外的位置產生了過大的存儲空間的消耗。比它消耗空間更少的一種方法:將x[0]存給臨時變量t,然後依次往前移動數組,重複操作i次。但是操作數過多,容易超時。從另外一面考察這個問題,可以得到一個不同的算法:旋轉向量x其實就是交換向量ab的兩段,得到向量ba。這裏a代表x中的前i個元素。假設a比b短,將b分爲bl和br,使得br具有與a相同的長度。交換a和br,也就將ablbr轉換爲(br)(bl)a。序列a此時已處於其最終的位置,因此現在的問題就集中到交換b的兩部分。由於新問題與原來的問題具有相同的形式,我們可以遞歸地解決之。使用該算法可以得到優雅的程序。解決過程:我們將問題看做是把數組ab轉換成ba,同時假定我們擁有一個函數可以將數組中特定部分的元素求逆。從ab開始,首先對a求逆,得到arb,然後對b求逆,得到arbr。最後整體求逆,得到(arbr)r。此時就恰好是ba。於是,我們得到了如下用於旋轉的代碼,其中註釋部分表示abcdefgh向左旋轉三個位置以後的結果。reverse(0,i-1)  /
cbadefgh /
reverse(i,n-1)  /
cbahgfed /
reverse(0,n-1)  /
defghabc */
大師就是不一樣,問題基於實際,不斷美化算法。還有變位詞判斷的題目,基於FBI查找罪犯(分分鐘做特工的感覺)的實例,詳細代碼及算法再贅述(雖然簡便移動,但是涉及文件調用)
明天繼續學習!很開心的一天~( ̄▽ ̄~)~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章