一道模擬賽的題

2021-08-17 14:39:00 字數 3465 閱讀 7694

這是乙個不錯的題啊,在這裡記錄一下

聽說不是原創題,那我就放上來了。。應該沒有關係吧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...