演算法俱樂部前兩次活動題目分析by邵明

2021-04-14 00:54:46 字數 4708 閱讀 3499

第一次討論

首先宣告一下:我寫的程式比較難看懂,有時候寫得長了如果回過去看,我自己也看不懂,而且在說明題意和方法上有些地方可能說的不是很清楚,自己的表達能力比較差,也請多多見諒。

第一題1058 currency exchange

這個題目就是一開始就給出五個國家的之間的匯率,然後題目中給乙個旅遊路線和開始旅遊前的錢數,然後問題是計算出經旅遊後手中還有多少錢。

這個問題我就模擬了一下,比較苯的辦法,沒什麼演算法可言。

具體**如下:

#include "stdafx.h"

#include "stdio.h"

int main(int argc, char* argv)

curr_city=0;

m=rate[last_city][curr_city]*m;

m=m*100;

temp_m=int(m);

if(m-temp_m>=0.5)

m=temp_m+1;

else

m=temp_m;

m=m/100;

printf("%

.2f/n",m); }

if(num!=1)

printf("/n");

num--; }

return 0; }

第二題1024 calendar game

題目我沒做,是乙個博弈題目,大概題意是由兩個人在玩日曆遊戲,每個人輪流走,可以選者走下一天,也可以走到下乙個月的這一天,比如當前你在

2002

年1 月

2 日

,你可以走到

1999

年1 月

3 日

或者1999

年2 月

2 日

,但是如果下乙個月沒有這天的話你只能走下一天,比如

1999

年1 月

30 日

,但是下個月沒有

30號,所以你唯一的選擇是走到

1999

年1 月

31 日

。誰先走到

2001

年 11

月 4

日 後面誰就輸了。有兩個人比賽

adam

和eve

,adam

先走,看

adam

有沒有策略可以贏。有的話輸出

yes,否則輸出no。

以下思路是學姐提供的,用乙個一維的陣列儲存每一天

adam

有沒有贏得策略,有的話存

1,沒的話存

0,剛開始從

2001

年11 月

3 日

開始存1

,後面的話是根據前一天或前乙個月的狀態來決定這天的狀態,依次類推。比如

2000

年3 月

2 日

可以根據

2000

年3 月

3 日

或2000

年4 月

2 日

決定,只要有乙個為0,

2000

年3 月

2 日

這一天才可以設為

1。具體程式沒實現過,想想應該可以的。

第三題1161 gone fishing

題目是叫我們求出在規定的時間內最多可以釣到的魚的條數。題目給了我們可用的時間

h,湖的個數

n,每個湖初始魚的條

f,每在乙個湖裡釣五分鐘之後魚的數目的減少量

d,從前乙個湖到後乙個湖需要花費的時間

t,湖與胡之間的路是單項的,就是一旦走到後面乙個湖上去了就不能回來。這道題可以用貪性演算法做。釣魚的湖從第乙個湖,前兩個湖,前三個一直往後推,然後比較哪個方案釣的魚比較多。每次都是先把湖與湖之間的耗費時間先剪掉,然後挑那個魚最多的湖釣,更新湖裡魚的條數,再在有最多魚的湖裡釣,依次類推,直到時間花完。

具體**如下:

#include "stdafx.h"

#include "iostream.h"

int main(int argc, char* argv)

need_h=need_h+ti[i];

temp_h=h-need_h;

if(temp_h<=0)

break;

while(temp_h>0)

}if(temp_fi[k]<=di[k])

temp_fi[k]=0;

else

temp_fi[k]=temp_fi[k]-di[k];

temp_max=temp_max+max_fi;

temp_time[k]++;

temp_h--;

}if(temp_max>max)

}for(j=0;j

cout<

cout<<"number of fish expected: "< }

return 0;

}第四題

1303 jury compromise

題目講的是有乙個國家在審案子的時候都要組建乙個陪審團,陪審團的成員是從候選的人群中選出來的。這些候選的人每個人都有兩個值,分別代表被告和原告給他們的值,從

0-20,0

代表對此人很厭惡,

20表示對此人非常滿意。我們的任務是要從這些人中選出一些人滿足最佳要求。

d(j)=

∑d(i) 1=∑

p(i) 1=是陪審團的人數。最佳要求就是

|d(j)-p(j)|

最小,當有兩組選擇,他們的

|d(j)-p(j)|

一樣,那麼選那組使

|d(j)+p(j)|

最大的。

本題用動態規劃做。我也是看了別人的思路才知道怎麼做的,但是還沒提交成功,路徑的儲存還沒解決。大概思路是這樣的:

列舉出所有的得分差,然後求最高得分和。由於m是從

0~20

,d(j)-p(j)

的差值是從

-20~20

的,所以得分差從

-400~400

,有801

種可能,可以開乙個三維陣列

cost[201][21][801]

,cost[i][j][k]

表示從前

i個人中選

j個人時得分差為

k的最高得分和。

遞推公式是

cost[i][j][k]=max(cost[i-1][j][k],cost[i-1][j-1][k-diff[i]]+sum[i]) diff[i]

,sum[i]是第i

個人的差值和和值。等表全部填完後,檢察

cost[n][m][k]

,如果cost[n][m][k]

存在,選

k值最小的就是答案了。

第二次討論

第一題1076 gene assembly

題目的意思是給你一組核苷酸,每乙個都有開始和結束,我們的問題是從這些核苷酸中找出能組成的最長的鏈,要求在鏈中前乙個核苷酸的結束要比後乙個核苷酸的開始要早。這題是用貪心演算法。先根據結束時間排序,結束時間早的排在前面。然後選擇第乙個核苷酸,再在剩下的裡面找到與這個核苷酸相容的第乙個核苷酸,找完後,再在剩下的裡面找與第二個相容的第乙個核苷酸,依次類推,直到沒有核苷酸可找,就停止。

具體**如下:

#include "stdafx.h"

#include "iostream.h"

int main(int argc, char* argv)

for(i=2;i<=n;i++)

else

break;

}start[j+1]=temp_start;

end[j+1]=temp_end;

num[j+1]=temp_num;

}number=1;

path[1]=num[1];

last_num=1;

j=2;

i=2;

while(i<=n)

else

i++;

}//cout<

for(i=1;i

cout<

cout< }

return 0;

}第二題

1203 swordfish

題目是給我們一組城市的二維座標,計算一條路徑能把所有的城市連起來的但總的距離最小的通路。就是最小生成樹問題。

具體**如下:

#include "stdafx.h"

#include "stdio.h"

#include "math.h"

int main(int argc, char* argv)

}for(i=1;i<=n;i++)

know[i]=0;

know[1]=1;

cost=0;

for(i=2;i<=n;i++)}}

if(min!=100000000)

}printf("case #%d:/n",number);

printf("the minimal distance is: %

.2f/n",cost);

number++;

}return 0;

}第三題

1082 stockbroker grapevine

這道題目是最短路徑,求城市到別的城市的最短路徑。可以用最短路徑演算法解決。

es java 聚合方法 兩次排序等同於兩次分組

兩次排序,第二次排序是在第一次排序的基礎上進行排序,並不會打亂第一次排序的結果,等同於兩次分組 test public void doublesort system.out.println 已排序 searchresponse response client.preparesearch indexn...

某摧殘我兩次的題目 螞蟻

n只螞蟻放在乙個長管 長度l 裡移動,每只螞蟻初始位置隨機 與管子左端距離分別為x 1 x n 他們的頭朝向左或右,移動速度相同均為 v,螞蟻長度忽略不計,任意兩隻相遇後掉頭反方向移動,螞蟻移到管子的左右出口就掉出去。問所有螞蟻都掉出去需要多久?寫出推理過程。在網易遊戲的筆試上遇到的題,當時沒做出來...

OpenParty成都2月3月兩次活動總結

openparty成都在過去的這個週六 3月10日 如期舉行了3月份的活動,活動介紹見 這次活動和上個月的活動 一樣 2月11日 人氣爆滿,話題豐富有趣。這都要歸功於瑤美女帶來了很多人氣。兩次活動的人數都達到將近40人左右。在這裡,要簡單總結的是我在這兩次活動上分別作的兩個簡短的主題演講 light...