思維 觀察 細節 刪除 紀中集訓

2021-09-25 20:17:04 字數 3228 閱讀 7230

alice上化學課時又分心了,他首先畫了乙個3行n列的**,然後把數字1到n填入**的第一行,保證每個數隻出現一次,另外兩行他也填入數字1到n,但不限制每個數字的出現次數。

alice現在想刪除若干列使得每一行排完序後完全一樣,程式設計計算最少需要刪除多少列。

第一行包含乙個整數n(1<=n<=100000),表示**的列數。

接下來三行每行包含n個整數,每個數在1到n之間,而且第一行的數互不相同。

輸出最少需要刪除的列數。

輸入1:

75 4 3 2 1 6 7

5 5 1 1 3 4 7

3 7 1 4 5 6 2

輸入2:

91 3 5 9 8 6 2 4 7

2 1 5 6 4 9 3 4 7

3 5 1 9 8 6 2 8 7

輸出1:

4輸出2:

2【樣例解釋】

例1中alice需要刪除第2、4、6、7這四列,然後每行排完序都是1、3、5。

【資料範圍】

40%的資料n<=100

70%的資料n<=10000

考試的時候猜了乙個顯而易見的結論:

在第二行中沒有出現的數出現在了第一行或第三行中的某一列,那麼這一列必須要刪掉。同理,在第三行中沒有出現的數出現在了第一行或第二行中的某一列,那麼這一列也必須要刪掉。

試了一下,第一組樣例過不去,再猜了乙個結論:他最終是要同一種數最多只能出現相同的次數,而第一行又是乙個排列,所以每個數最多出現一次,那麼就把出現次數大於1次的刪去。由於時間所剩無幾,我碼了一下過了樣例就交了。

出分的時候原版**只有20分,把vis

visvi

s陣列去掉壓在cnt

cntcn

t陣列(**中的t1和t2)裡面有40分

//20pts

#include

#include

#include

using

namespace std;

#define maxn 100005

#define inf 0x3f3f3f3f

#define ll long long

int n,a[maxn]

,b[maxn]

,c[maxn]

,t1[maxn]

,t2[maxn]

,ans;

bool vis1[maxn]

,vis2[maxn]

;int

main()

for(

int i=

1;i<=n;i++

)for

(int i=

1;i<=n;i++

)for

(int i=

1;i<=n;i++)if

(t1[b[i]

]>=

2||t2[c[i]

]>=2)

ans++

,t1[b[i]]--

,t2[c[i]]--

;printf

("%d\n"

,ans)

;return0;

}

//40pts

#include

#include

#include

using

namespace std;

#define maxn 100005

#define inf 0x3f3f3f3f

#define ll long long

int n,a[maxn]

,b[maxn]

,c[maxn]

,t1[maxn]

,t2[maxn]

,ans;

intmain()

for(

int i=

1;i<=n;i++

)for

(int i=

1;i<=n;i++

)for

(int i=

1;i<=n;i++)if

(t1[b[i]

]>=

2||t2[c[i]

]>=2)

ans++

,t1[b[i]]--

,t2[c[i]]--

;printf

("%d\n"

,ans)

;return0;

}

而造成這個差異的原因是:有可能在做前面操作的時候對其它做了貢獻,因為t1[

],t2

[]

t1,t2

t1,t

2[]都有變化,所以要用t1[

],t2

[]

t1,t2

t1,t

2[]來判斷,而不能看最開始的vis

visvi

s陣列。

同理,在做其它操作的時候可能會導致t1[

],t2

[]

t1,t2

t1,t

2[]的變化,所以可能出現有新的列滿足被刪的條件,所以要一直遍歷陣列,重複做這種操作。做多少次呢?直到它不再更新為止。

我猜的第二個結論也是錯的,它不能保障最少,因為第乙個結論刪去的是必須刪的,所以會最少,但是第二個結論中,有很多個那些數的時候刪哪些數呢?顯然是不能隨便刪的。(可是我就是隨便刪了)

還有乙個致命的錯誤在考場上沒有注意到,我們需要用乙個陣列標記當前列是否已經被刪,如果已經被刪,則不能再次刪它qwq 我居然連這個都沒有注意到,實在是太菜了

#include

#include

#include

using

namespace std;

#define maxn 100005

#define inf 0x3f3f3f3f

#define ll long long

int n,a[maxn]

,b[maxn]

,c[maxn]

,t1[maxn]

,t2[maxn]

,ans;

bool vis[maxn]

;int

main()

for(

int i=

1;i<=n;i++

)bool f=0;

do}while

(f);

printf

("%d\n"

,ans)

;return0;

}

紀中集訓2019 11 05

題目鏈結 有 n 個點,求 n 1 個完美匹配,且其中不出現相同的邊。n le 10 3 打暴力 手玩找到規律。把匹配放到方格圖上,給屬於同乙個完美匹配的方格染上同樣的顏色,發現兩個性質 最後一列第一行填 n 之後往下從小到大填完偶數,再從小到大填完奇數 forall i in 1,n 1 從 1,...

紀中集訓 遊戲

題目鏈結 是紀中的題,不過我已經沒有紀中的號了,於是翻出了我的古早部落格 複習的時候又做了一遍,還是想了一會兒的,並且由衷地覺得這真是一道好題。考慮 sg 函式遞推。由於每次操作只能動最後一行和最後一列,那麼設 sg i,j 表示以 i,j 結尾的矩陣的 sg 函式值。轉移有 sg i,j mex ...

紀中集訓2019 3 21 橋

描述 有 m 條河,每條河的兩邊有居民點,所以共有 m 1 排居名點 如果要從一排居名點到另一排相鄰的居民點需要過河 現在有 n 個人,每個人的起點座標是 p s 終點 q t 你可以在每條河上修建一座橋,過河必須通過橋 相鄰居民點距離為 1 不考慮過河的時間 問 n 個人到終點的路徑之和最小是多少...