導彈防禦塔(題解+程式碼)
Description
Freda的城堡——
“Freda,城堡外發現了一些入侵者!”
“喵…剛剛探究完了城堡建設的方案數,我要歇一會兒嘛lala~”
“可是入侵者已經接近城堡了呀!”
“別擔心,rainbow,你看呢,這是我剛設計的導彈防禦系統的說~”
“喂…別賣萌啊……”
Freda控制著N座可以發射導彈的防禦塔。每座塔都有足夠數量的導彈,但是每座塔每次只能發射一枚。在發射導彈時,導彈需要T1秒才能從防禦塔中射出,而在發射導彈後,發射這枚導彈的防禦塔需要T2分鐘來冷卻。
所有導彈都有相同的勻速飛行速度V,並且會沿著距離最短的路徑去打擊目標。計算防禦塔到目標的距離Distance時,你只需要計算水平距離,而忽略導彈飛行的高度。導彈在空中飛行的時間就是 (Distance/V) 分鐘,導彈到達目標後可以立即將它擊毀。
現在,給出N座導彈防禦塔的座標,M個入侵者的座標,T1、T2和V,你需要求出至少要多少分鐘才能擊退所有的入侵者。
Solution
題目要求所有目標被擊毀的時間最大值最小,所以我們可以考慮二分答案(這是一個很重要的方法)
我們考慮如何在當前二分的答案下儘量多的打擊目標
由於每個防禦塔都可以發射任意發導彈攻擊,所以我們不妨把每個防禦塔都先打出去M發導彈
把能在時間限制內打出的每發導彈都和這發導彈能在時間範圍內打到的目標連一條邊
然後題目就轉化成經典的二分圖最大匹配
用匈牙利或者網路流跑一遍就好了
匈牙利又短又快,強烈建議打匈牙利(網路流非常非常的長)
下面只貼匈牙利的程式碼
Code
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cmath>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fod(i,a,b) for(i=a;i>=b;i--)
using namespace std;
int a[2560][2560],fr[51][2],mt[51][2],n,m,t2,v;
double t1,ti[2560];
double mid;
int dt[51],s;
bool bz[1002];
double dis(int p,int q)
{
int x1=fr[(p/m)+(p%m!=0)][0],y1=fr[(p/m)+(p%m!=0)][1],x2=mt[q][0],y2=mt[q][1];
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
bool find(int k)
{
int i,j;
if (ti[k]>mid) return 0;
fo(i,1,a[k][0])
{
int p=a[k][i];
if (bz[p]==0&&ti[k]+dis(k,p)/v<=mid)
{
bz[p]=1;
if (dt[p]==0||find(dt[p]))
{
dt[p]=k;
return 1;
}
}
}
return 0;
}
int main()
{
freopen("freda.in","r",stdin);
cin>>n>>m>>t1>>t2>>v;
int i,j,k;
t1=t1/60;
double l,r;
for(i=1;i<=m;i++)
{
scanf("%d%d",&mt[i][0],&mt[i][1]);
}
fo(i,1,n)
{
scanf("%d%d",&fr[i][0],&fr[i][1]);
fo(j,1,m)
{
ti[(i-1)*m+j]=(j-1)*(t1+t2)+t1;
fo(k,1,m)
{
a[(i-1)*m+j][++a[(i-1)*m+j][0]]=k;
}
}
}
l=1;
r=40000;
n*=m;
while (r-l>1e-7)
{
mid=(l+r)/2;
int ans=0,v=0;
memset(dt,0,sizeof(dt));
fo(i,1,n)
{
memset(bz,0,sizeof(bz));
ans+=find(i);
}
if (ans==m) r=mid;
else l=mid;
}
printf("%.6lf",l);
}
相關推薦
導彈防禦塔(題解+程式碼)
Description Freda的城堡—— “Freda,城堡外發現了一些入侵者!” “喵…剛剛探究完了城堡建設的方案數,我要歇一會兒嘛lala~” “可是入侵者已經接近城堡了呀!” “別擔心,rainbow,你看呢,這是我剛設計的導彈防禦系統的說~
漢諾塔遊戲的設計(附程式碼)
漢諾塔遊戲的設計 漢諾塔問題是最經典的遞迴問題,筆者就該問題設計了這個遊戲,由使用者互動遊戲和自動演示兩部分組成,支援撤銷功能、選關、自動完成等功能。 首先建立了類CMap,該類主要實現使用者每一步的操作和畫圖顯示功能,記錄的時候只須記錄每組盤子的個數和盤子的矩形。程
漢諾塔C語言實現(純程式碼)
(本篇只為記錄程式碼,不加註解)a、b、c三座塔,將n個從小到大(自上而下)的圓盤從a移動到c,移動期間小圓盤必須在大圓盤上面,問移動步驟。#include<stdio.h> int main() { void hanoi(int n,char one
3156: 防禦準備(斜率優化)
return getchar() == div lan 前綴 php 查點 準備 鏈接 思路 斜率優化。 f[i] 表示i點建檢查點的花費。 f[i] = f[j] + i*(i-j-1)-(s[i-1]-s[j]) + a[i],從j轉移,s為前綴和
hadoop編寫MapReduce例子(附有程式碼)
開發環境:hadoop2.6.5, jdk1.8. ubuntu14系統 1.在本地寫好程式碼(eclipse寫的,當時沒用maven,直接把jar引到程式裡了) 2.打成jar包(eclipse右鍵專案,點選export,選擇jar包型別),打jar包的時
java8使用Optional來避免空指標異常(簡化程式碼)
在最近的開發中遇到不少java.lang.NullPointerException異常 ,而為了避免這個異常,不免要利用if-else來進行判斷。比如如下的程式碼: public static void main(String[] args) { Lis
Java併發程式設計(2):執行緒中斷(含程式碼)
使用interrupt()中斷執行緒當一個執行緒執行時,另一個執行緒可以呼叫對應的Thread物件的interrupt()方法來中斷它,該方法只是在目標執行緒中設定一個標誌,表示它已經被中斷,並立即返回。這裡需要注意的是,如果只是單純的呼叫interrupt()方法,執行緒並沒有實際被中斷,會繼續往下執行。
導彈防禦塔---二分圖匹配《lyd演算法進階》
題目描述 Freda控制著N座可以發射導彈的防禦塔。每座塔都有足夠數量的導彈,但是每座塔每次只能發射一枚。在發射導彈時,導彈需要T1秒才能從防禦塔中射出,而在發射導彈後,發射這枚導彈的防禦塔需要T2分鐘來冷卻。 所有導彈都有相同的勻速飛行速度V,並且會沿著距離最短的路徑去打擊目標。計算防禦塔
Java併發程式設計(3):執行緒掛起、恢復與終止的正確方法(含程式碼)
JAVA大資料中高階架構 2018-11-06 14:24:56掛起和恢復執行緒Thread 的API中包含兩個被淘汰的方法,它們用於臨時掛起和重啟某個執行緒,這些方法已經被淘汰,因為它們是不安全的,不穩定的。如果在不合適的時候掛起執行緒(比如,鎖定共享資源時),此時便可能會發生死鎖條件——其他執行緒在等待該
springboot操作資料庫總結(流程圖+程式碼)
springboot提供了很多種操作資料庫的方式,大致思路都差別不大,只是使用的一些細節存在差異。 1.JpaRepository spring data有一個分支為spring data JPA,是專門針對J
Java併發程式設計(5):volatile變數修飾符-意料之外的問題(含程式碼)
volatile用處說明在JDK1.2之前,Java的記憶體模型實現總是從主存(即共享記憶體)讀取變數,是不需要進行特別的注意的。而隨著JVM的成熟和優化,現在在多執行緒環境下volatile關鍵字的使用變得非常重要。 在當前的Java記憶體模型下,執行緒可以把變數儲存在本地記憶體(比如機器的暫存器)中,而
半邊資料結構與網格細分演算法Loop subdivision(附程式碼)
網格細分的原理其實並不難理解,它的難點主要在於如何實現。在看過無數有原理無程式碼的部落格後,終於決定寫一寫我的實現方法,並附上程式碼供大家參考。c++寫的可能比較笨拙,望見諒。 1.半邊資料結構 很好理解,就是把網格的每一條邊分成兩個半邊,半邊是有方向的同一條邊的兩個半邊方向相反。並且一條邊
辛普森公式(理論+程式碼)
數學分析中的泰勒公式告訴我們,對任何函式,我們都可以用多項式函式去逼近它的函式值,且對於解析性質很好的函式(例如任意階可導+任意階導函式有界),我們可以將誤差縮小到任意小。 其中 那麼,我們在求解析式複雜或者可能無法用初等函式表示原函式的積分問題時,能否也可以用多項式函式來代替呢? 辛普
長按事件(完整程式碼)長按觸發
直接新建個html把程式碼全部放裡面,檢視效果! <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title></title> <scr
Java併發程式設計(8):多執行緒環境中安全使用集合API(含程式碼)
Java併發程式設計(8):多執行緒環境中安全使用集合API(含程式碼)JAVA大資料中高階架構 2018-11-09 14:44:47在集合API中,最初設計的Vector和Hashtable是多執行緒安全的。例如:對於Vector來說,用來新增和刪除元素的方法是同步的。如果只有一個執行緒與Vector的例
Java併發程式設計(9):死鎖(含程式碼)
JAVA大資料中高階架構 2018-11-10 14:04:32當執行緒需要同時持有多個鎖時,有可能產生死鎖。考慮如下情形: 執行緒A當前持有互斥所鎖lock1,執行緒B當前持有互斥鎖lock2。接下來,當執行緒A仍然持有lock1時,它試圖獲取lock2,因為執行緒B正持有lock2,因此執行緒A會阻塞等
漢諾塔(遞迴)
閱讀遞迴函式最容易的方法不是糾纏於它的執行過程,而是相信遞迴函式會順利完成它的任務。如果你的每個步驟正確無誤,你的限制條件設定正確,並且每次呼叫之後更接近限制條件,遞迴函式總是能夠正確地完成任務。——《C和指標》 一、遊戲規則 有三個塔,第一個塔上放了若干個盤子。要將這若干個盤子
ROI Align 在 R-FCN 中的推廣:PSROI-Align(附程式碼)
ROI Align 在 R-FCN 中的推廣:PSROI-Align(附程式碼) 1. Position Sensitive ROI-Pooling 簡介 原文:https://blog.csdn.net/Bruce_0712/article/details/80287355 原始碼解析
遞迴的應用——斐波那契數列、漢諾塔(Java實現)
package ch06; public class Fibonacci { public static int getNumber(int n) { if(n == 1) { return 0; } else if(n == 2){
如何修改Klocwork掃描出來的問題(C程式碼)
下面是自己修改Klocwork掃描出來的問題的心得體會: 1、凡是malloc申請空間以後,記得考慮malloc失敗的這種情況 p=malloc() if(p==NULL)return ; 2、函式結束時,凡是malloc的,記得用free釋放,對於獲取的控制代碼指