CF習題集二

2022-01-10 17:38:00 字數 3542 閱讀 1214

\(breaking good\)這個遊戲對於有經驗的玩家來說也有一定的難度。

遊戲的主角小明希望加入乙個叫斧頭幫的犯罪團夥。這個團夥控制著整個國家\(n\)個城市間的\(m\)條雙向道路,這些道路保證沒有自環和重邊,任何城市可以通過這些道路到達任何其他城市。

然而道路並不全都能通行,有些道路是需要修復。

現在這個團夥要搞乙個大新聞!搞事地點位於城市\(1\)。像往常一樣,這個行動最難的部分是搞事後如何逃到他們在城市n的總部。為了獲得該團夥的信任,小明決定負責這項搞事行動,而且他提出了乙個看起來很明智的計畫。

首先,他們將在從城市1返回途中使用的路徑總長度必須盡可能短;然後,為了讓搞的大新聞更加刺激,他們必須炸毀所有不在這條路徑上的其他道路。但是他們不必炸掉不能通行的道路。

如果選擇的道路有一些不能通行的道路,他們將不得不在行動之前修復那些道路。

小明發現,有很多路徑滿足了條件\(1\)(即盡可能短),所以他決定在其中選擇一條路徑,使受影響道路的總數最小化。

你能幫助小明完成搞事並獲得該團夥的信任嗎?

首先,我們要選擇一條最短的路徑

在路徑最短的基礎上,我們要盡量使受影響的道路數更少

因此我們要在跑\(dij\)的結構體裡儲存三個東西

即當前節點的編號,當前節點距離起點的最短路徑,當前路徑下更改的道路條數

在進行鬆弛操作時,如果\(dis[u]>dis[now]+b[i].val\)

那麼我們像之前那樣更新\(dis\)值即可

如果\(dis[u]=dis[now]+b[i].val\)但是新的路徑更改的道路條數更少

此時我們也需要更新

#includeusing namespace std;

const int maxn=1e6+5;

int head[maxn],tot=1;

struct asdb[maxn];

void ad(int aa,int bb,int cc,int dd)

struct jie

bool operator < (const jie& a) const

};priority_queueq;

bool viss[maxn];

int dis[maxn],jl[maxn],hf[maxn];

void dij() else if(dis[u]==dis[now]+b[i].val)}}

}}vectorg;

bool vis[maxn];

int main()

dij();

int ans=0;

int now=n;

while(jl[now])

for(int i=0;i**手機 \(itone6\) 近期上市,\(george\) 很想買乙隻。不幸地,\(george\) 沒有足夠的錢,所以 \(george\) 打算當一名程式猿去打工。現在\(george\)遇到了乙個問題。 給出一組有 \(n\) 個整數的數列\(p_1,p_2,...,p_n\),你需要挑出 \(k\) 組長度為 \(m\) 的數,要求這些數互不重疊 即$ [l_,r_],[l_,r_],...,[l_,r_] (1<=l_<=r_使選出的數的和值最大,請你幫助george碼出這份**

我們設\(f[i][j]\)為前\(i\)個數選出了\(j\)組,其中第\(i\)個數必須選的最大值

那麼我們就可以寫出如下的狀態轉移方程

f[i][k]=max(f[i][k],f[j][k-1]+sum[i]-sum[i-m]);

時間複雜度為\(o(n^3)\)

實際上,我們可以用單調佇列對於每乙個\(i\)維護\(f[j][k-1]\)的最大值

這樣時間複雜度就降到了\(o(n^2)\)

#includeusing namespace std;

const int maxn=5e3+5;

#define int long long

int sum[maxn],a[maxn],f[maxn][maxn],q[maxn],head,tail;

signed main()

int ans=0;

for(int j=1;j<=p;j++)

}printf("%lld\n",ans);

return 0;

}

在乙個平面內給出\(n\)個點的座標,任選其中三個為圓心作半徑相同的圓,要求這三個圓不能相交但可以相切,求能畫出的圓中的最大半徑。

對於平面上的三個點,我們可以將其分為兩種情況

一種情況是三個點都位於一條直線上

此時我們的最大直徑只能是三點當中距離最小的兩點的距離

還有一種情況是三個點不在同一條直線上

此時我們的最大直徑也只能是三點當中距離最小的兩點的距離

因為我們要保證圓只能相切,不能相交

如果直徑再大一點,勢必會出現相交的情況

所以我們可以先預處理出任意兩點間的距離,然後按距離從小到大排好序

每次取出兩個點,我們就判斷一下它們是否和同乙個點已經連到一起

如果已經連到一起,我們就輸出當前答案,否則繼續尋找

而判斷兩個點是否和同乙個點連到乙個我們可以用\(bitset\)解決

#includeusing namespace std;

typedef double dd;

const int maxn=3005;

dd jlx[maxn],jly[maxn];

bitsetg[maxn];

struct asdb[maxn*maxn];

dd solve(int aa,int bb)

bool cmp(asd aa,asd bb)

int main()

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

}sort(b+1,b+1+cnt,cmp);

for(int i=1;i<=cnt;i++)

}return 0;

}

很多人把\(logo\)程式語言和海龜圖形聯絡起來。在這種情況下,海龜沿著直線移動,接受命令「t」(「轉向180度」)和「f」(「向前移動1單元」)。

你會收到乙份給海龜的命令清單。你必須從列表中精確地改變n個命令(乙個命令可以被改變多次)。要求出海龜在遵循修改後的所有命令後,會從起點最遠可以移到多遠?

傳送門

#includeusing namespace std;

const int maxn=105;

char s[maxn];

int f[maxn][maxn][3],wz[maxn];

int main()

} scanf("%s",s+1);

int n;

scanf("%d",&n);

int len=strlen(s+1);

f[0][0][0]=0;

f[0][0][1]=0;

for(int i=1;i<=len;i++) else

} else else }}

} }printf("%d\n",max(f[len][n][0],f[len][n][1]));

return 0;

}

資料結構習題集(二)

n項物品,大小分別為s 1 s 2 s i s n 其中s i 為滿足1 s i 10 0的整數。要把這些物品裝入到容量為100的一批箱子 序號1 n 中。裝箱方法是 對每項物品,順序掃瞄箱子,把該物品放入足以能夠容下它的第乙個箱子中。請寫乙個程式模擬這種裝箱過程,並輸出每個物品所在的箱子序號,以及...

Python習題集(四)

如果乙個 3 位數等於其各位數字的立方和,則稱這個數為水仙花數。例如 153 1 3 5 3 3 3,因此 153 就是乙個水仙花數 那麼問題來了,求1000以內的水仙花數 3位數 int轉字串序列,獲取到每一位數 呼叫math.pow函式求立方和 三個數字立方和相加 lists for i in ...

Python習題集(十二)

請寫乙個函式find odd,引數是1個列表,請返回該列表 現奇數次的元素 比如 find odd 1,1,2,2,5,2,4,4,1,2,5 1 find odd 20,1,1,2,2,3,3,5,5,4,20,4,5 5 find odd 10 10 迴圈列表 呼叫列表內建統計函式計算當前元素出...