這是乙個不錯的題啊,在這裡記錄一下
聽說不是原創題,那我就放上來了。。應該沒有關係吧qaq
有乙個 n × m 的地圖, 地圖上的每乙個位置可以是空地, 炮塔或是敵人. 你需要操縱炮塔消滅敵人.對於每個炮塔都有乙個它可以瞄準的方向, 你需要在它的瞄準方向上確定乙個它的攻擊位置,當然也可以不進行攻擊. 一旦乙個位置被攻擊, 則在這個位置上的所有敵人都會被消滅.保證對於任意乙個炮塔, 它所有可能的攻擊位置上不存在另外乙個炮塔.定義炮彈的執行軌跡為炮彈的起點和終點覆蓋的區域. 你需要求出一種方案, 使得沒有兩條炮彈軌跡相交.求消滅最多的敵人
首先,你要注意到保證對於任意乙個炮塔, 它所有可能的攻擊位置上不存在另外乙個炮塔.這個條件。我當時就沒有注意到qaq
語文太差了
考場的時候沒有想出來啊
但總感覺是一種網路流之類的東西,但是不知道怎麼建圖
這裡提供兩種建圖方法,都很秒啊
這種方法在隨機資料上表現良好,但是可以被人為構造卡掉
但是卡掉的時候也不是特別慢。。但是思路還是很妙的
我們考慮到,如果把向行發射的炮塔看做是a點,向列發射的炮塔看做是b的點。
那麼顯然地,只有a和b會互相影響
a和a是不會影響的
於是我們可以把他看做乙個二分圖
但是有乙個問題,那就是,對於每乙個炮塔,他只可以打他最大的乙個,二不能打多個
那麼a自己本身對自己也有限制,那怎麼辦呢?
我們知道,如果我們暴力這麼建圖,那麼最後的答案,是a點可以打連續一段的答案,這不是我們想要地
我們考慮到,對於乙個a,如果他打得遠,那麼肯定是為了更大的代價,因此,他可以決策的地方的值肯定是單調上公升的
我們可以吧這些點找出來
然後對於這些點的權值差分一下,就可以完美地解決問題了
然後剩下怎麼做,你就把x打到y看做乙個點就可以了
直接最小割上就好了
但是這個方法點數和邊數可以被卡的很大
code:
#include
#include
#include
#include
#include
using
namespace
std;
const
int max=1
<<30;
const
int n=55;
int n,m;
int a[n][n];
struct qt
s[2][5005*2];//每乙個點的資訊
struct qq
e[5005*5005];int num,last[5005*2];
int st,ed;
void init (int x,int y,int z)
int tot[2];
int x[4]=;
int y[4]=;
bool ok (int x,int y)
bool check (qt y,qt x)//x是豎著的,y是橫著的
int h[5005*2];
bool bt ()}}
return h[ed]!=-1;
}int dfs (int x,int f)
}if (s1==0) h[x]=-1;
return s1;
}int main()
x=x+x[tt];y=y+y[tt];}}
st=tot[0]+tot[1]+1,ed=st+1;
int sum=0;
for (int u=1;u<=tot[0];u++)
for (int u=1;u<=tot[1];u++)
for (int u=1;u<=tot[0];u++)
for (int i=1;i<=tot[1];i++)
}while (bt()) sum=sum-dfs(st,max);
printf("%d\n",sum);
return
0;}
這個構圖方法就不怕被卡了,思路也很好啊
考慮最小割模型.
考慮分別對橫著的和豎著的炮, 把它們覆蓋的點連成一條鏈 (當然直接跑網路流求的是最小值,需要用乙個大數減去).如何體現」 不能相交」 的限制呢?
我們將先將橫著的鏈建好, 再反著建豎著的鏈, 最後將每個相交的鏈之間連一條無窮大邊, 這樣就可以保證求出來的最小割是合法的了.
這個的話,理解起來就是我們所要知道的是每個炮台打到哪乙個點停下來
乙個是從ed開始往前看的
乙個是從st開始忘後看的
如果停的位置跨過了別的炮台的軌道,那麼別的軌道就要在這個點之前停下來了
這樣的話,建圖也很顯然了
並且點數和邊數都是很少的
update4.8
複習這個題的時候發現**好像不是我想的啊。。
可能是我貼錯了
但是現在我當時bac的**已經沒了。。
貼乙個唐隊隊的吧
這個保證是對的,我仔細看了一下,和我記憶中的做法是一樣的
code:
#include
#include
#include
#include
#include
using
namespace
std;
const
int inf=(1
<<30);
const
int maxn=6000;
int n,m,n1[55][55],n2[55][55],c1=0,mp[55][55];
int mark[55][55];
struct edgee[2110000];
int len=1,last[maxn];
void ins(int x,int y,int d)
void addedge(int x,int y,int d)
int st,ed;
int h[maxn];
bool bfs()
}return h[ed];
}int dfs(int x,int f)
}if(s==0)h[x]=0;
return s;
}int main()
else
if(mp[i][j]==-2)
}for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
n2[i][j]=++c1;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
addedge(n2[i][m],ed,inf);
}else
if(mp[i][j]==-3)
addedge(n2[i][1],ed,inf);}}
while(bfs())ans-=dfs(st,inf);
printf("%d",ans);
}
一道模擬題
問題 把英文單詞表示的數字轉換為阿拉伯數字,要求數字不超過整形範圍,數字形如abc,def,hrg。第一行表示有幾組資料,第二行輸入英文。輸出 相應的阿拉伯數字。例如 input eleven one hundred and two output 分析 要注意百萬和千要斷位,還有要從高位往低位查詢,...
記一道模擬題
今天也沒幹啥,長時間不運動,身體似乎倍感不適,宿舍一天到晚也沒有陽光照進來,實在是讓人難受,我那幾雙臭鞋也越發那啥了.趁著還有點時間,寫了一道模擬題,總是有愛看題解的臭毛病,今天終於忍住沒看,自己寫出來了。還是挺高興的。是洛谷原創的題目,題目背景是我的世界,計算乙個 n n的方塊中會出現多少怪物。想...
NOIP模擬賽 一道挖掉背景的數學題
time limit 1000 ms memory limit 131072 kbytes 給定n與p,求 left lfloor x n right rfloor p x frac 1 輸入一行,兩個非負整數n,p。輸出乙個整數,表示答案 5 97 今天寫道數學題吧owo 這道題我們看到 frac...