BestCoder Round 1 解題報告

2021-08-03 13:04:04 字數 4205 閱讀 9028

最近聽到splay學長說有乙個**叫bestcoder,題目質量挺不錯,而且難度在noip提高組水平,比較適合我刷(重點是不像cf那樣要翻牆,深夜打比賽,而且它還支援在hdu上提交)。於是我有空跑過去看了看,見到只有6頁比賽嘛,於是決定從頭開始做……但願暑假能刷完吧。

題目傳送門:

題目分析:剛開啟這題就見到了陳老師……一開始我覺得讓編號小的盡量靠前=字典序最小,然後覺得很水嘛,直到後來我舉出了反例。然後我開始腦洞大開yy,但想出來的方法基本都是時間複雜度玄學。我感覺從前往後放有困難,於是試圖從後面開始做。如果a要在b之前,就b向a連一條邊,然後每一次選編號最大的入度為0的點,並刪去它的出邊,就可以保證編號小的盡可能靠前。我感覺這個方法跟我做過的一道poj上的遞迴列印尤拉路徑的題有點像,直覺告訴我這樣做和原問題是等價的,但我不會證明。於是我上網找了一下,發現好像這就是正解,然而也沒有嚴格的證明……總之用優先佇列找編號最大,時間o(nlog(n))(像我這種從來不用stl庫的人當然只能手寫heap辣)

code:

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

const

int maxn=30010;

const

int maxm=100100;

struct edge

e[maxm];

edge *head[maxn];

int cur;

int pin[maxn];

int ans[maxn];

int heap[maxn];

int tail;

int t,n,m;

void add(int x,int y)

void insert(int x)

}int get()

return x;

}int main()

tail=0;

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

if (!pin[i]) insert(i);

for (int i=n; i>=1; i--)

ans[i]=x;

}for (int i=1; iprintf("%d ",ans[i]);

printf("%d\n",ans[n]);

}return

0;}

題目傳送門:

題目分析:這題比第一題要簡單一些吧。由於圖是聯通的,而且邊數隻比點數多10,那麼我們做一遍dfs,非樹邊的個數頂多11條。dfs的時候我們記valson[node]表示node的兒子的權值和。修改node的權值的時候改它本身的val值,和它父親的valson值即可。查詢答案的時候將它father的val加上它的valson,再暴力檢視非樹邊即可。

code:

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

const

int maxn=100100;

const

int maxm=13;

struct edge

e[maxn<<1];

edge *head[maxn];

int cur;

int cnt[maxn][maxm];

int val[maxn];

int fa[maxn];

int vson[maxn];

int t,n,m,q;

void add(int x,int y)

void dfs(int node)

}int main()

fa[1]=1;

dfs(1);

scanf("%d",&q);

while (q--)

else}}

return

0;}

題目傳送門:

題目分析:一道網路流好題啊。一開始我完全沒想到是最小割,往貪心,dp方面想了好久。上網瀏覽了一下題解,知道了是最小割,再回去想,還是不知道怎麼建圖。後來仔細看了題解,上面說它跟《最小割模型在資訊學競賽中的應用》裡面的一道例題 最優標號 optimal marks 很像,於是我跑過去把**讀了一遍,會做例題了,然而這題還是想不到怎麼做……

我們先在網格外圍一層」d」,然後這題的關鍵就在於最大化相鄰格仔中乙個是陸地,乙個是海洋的數量,即最小化相鄰格仔相同的數量。在**中討論了如何最小化相鄰格仔不同,但對於乙個普通的圖,要做到最大化不同格仔,是無法建圖跑網路流的。然而這裡我們是網格圖,我們可以對其進行黑白染色,將所有黑色的格仔反轉(即陸地->深海,深海->陸地,淺海->淺海)。這樣就變成了**中的情況。

這道題的難點在於往最小割方面去想,以及顏色反轉。反轉了之後就是乙個很簡單的模型,我們讓每乙個格仔都為乙個點,如果是深海,則s向其連無窮大的邊,它向t連1;淺海則兩個都為1;陸地則s連1,t連無窮大;相鄰格仔之間連一條容量為1的無向邊。最後用格仔數+相鄰格仔對數-最大流即可。

code:

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

const

int maxn=52;

const

int maxv=10010;

const

int maxm=1000000;

const

int oo=1000000000;

struct edge

e[maxm];

edge *head[maxv];

int cur;

edge *nhead[maxv];

int level[maxv];

int que[maxv];

int he,ta;

int t;

char s[maxn];

intmap[maxn][maxn];

int t,n,m;

int get(int x,int y)

void add(int x,int y,int xf,int yf)

bool bfs()

}return level[t];

}int dfs(int node,int maxf)

}if (maxf) level[node]=0;

return nowf;

}int dinic()

int main()

}for (int i=0; i<=m+1; i++) map[0][i]=map[n+1][i]=2;

for (int i=1; i<=n; i++) map[i][0]=map[i][m+1]=2;

for (int i=0; i<=n+1; i++) for (int j=0; j<=m+1; j++)

if ( (i+j)&1 ) map[i][j]=2-map[i][j];

/*for (int i=0; i<=n+1; i++)

*/t=(n+2)*(m+2)+1;

cur=-1;

for (int i=0; i<=t; i++) head[i]=null;

for (int i=0; i<=n+1; i++) for (int j=0; j<=m+1; j++)

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

for (int j=0; j<=m+1; j++)

int ans=dinic();

ans=(n+1)*(m+2)+(n+2)*(m+1)+(n+2)*(m+2)-ans;

printf("case %d: %d\n",g,ans);

}return

0;}

題目傳送門:

題目分析:計算幾何不可做……

Bestcoder round 32 解題報告

按照題目要求寫出cmp函式,sort一下就行了。include include include include include include using namespace std struct node a 1100000 int n int cmp node a,node b sort a,a...

BestCoder Round 40 解題報告

這場是第一場沒有公尺的bc.大概也是想震一震那些一聽說沒公尺了就不打bc的人吧 這次的題目質量比以往高了許多 然而我並沒有打這一場bc 但是今天下午到現在做的過程中真的學到了不少知識呢 a題略水.1 include2 include3 include4 include5 intt,n 6int ma...

1D1A 1 插入排序

演算法導論第乙個演算法就是插入排序,思想簡單,如果是從小到大排序,就是從第二個數開始,和前邊的數比較,直到大於等於前邊那乙個數,然後放在那個位置。而且,先用python寫,就相當於偽 特別好,既有思路,還把python練習一下,然後再用c python def insertsort a for i ...