10 3 校內集訓 解題報告

2021-08-28 16:45:03 字數 4602 閱讀 3313

題目背景

於大夫建造了乙個美麗的池塘,用來讓自己愉快的玩耍。這個長方形的池子被分割成了m 行和n 列的正方形格仔。池塘中有些地方是可以跳上的荷葉,有些地方是不能放置荷葉也不能跳上的岩石,其他地方是池水(當然於大夫也是不能游泳的)。

題目描述

於大夫十分有趣,他在池塘跳躍的方式和象棋中的馬一樣可以向八個方向走日字形,而且於大夫只能跳上荷葉。 於大夫每天從乙個給定的有荷葉的地方出發,試圖到達另乙個給定的有荷葉的地方。但有一天他發現自己無論如何也不能到達目的地了,除非再在水中放置幾個荷葉。於大夫想讓你告訴他,最少還需放置幾片荷葉?在放置荷葉最少的前提下,最少需要幾步能到達目的地?

輸入輸出格式

輸入格式:

第1 行: 兩個整數m , n 第2…m+1 行:第i + 1 行有n 個整數,表示該位置的狀態:

0 為水; 1 為荷葉; 2 為岩石; 3 為於大夫開始的位置; 4 為於大夫要去的目標位置.

輸出格式:

一行兩個整數空格隔開:分別為最少放置荷葉數和最小放置為前提下最少步數。(,如果無 論如何也不能到達請輸出-1 -1)。

輸入輸出樣例

輸入樣例#1: 複製

input1:

4 80 0 0 1 0 0 0 0

0 0 0 0 0 2 0 1

0 0 0 0 0 4 0 0

3 0 0 0 0 0 1 0

輸出樣例#1: 複製

2 6說明

10%的資料n,m<=4

30%的資料n,m<=10

50%的資料n,m<=30

70%的資料n,m<=50

100%的資料n,m<=100

所以這是道爆搜題…

可算是雙關鍵字爆搜吧,我們可以用priority_queue來維護我們的bfs佇列,定義所需荷葉數的優先順序大於路徑長度,因此我們第一次搜到終點,此時所需荷葉數最少,路徑長度最短,一定是最優解

ac code:

#include

#define rg register

#define il inline

#define maxn 500005

#define ll long long

using

namespace std;

il int

read()

while

(ch >=

'0'&& ch <=

'9')

return x * w;

}char ss[

1000];

int s1 , s2 , t1 , t2 , n , m;

bool vis[

102]

[102];

int f[

102]

[102];

int fx[8]

=, fy[8]

=;struct node};

node bfs

(int x ,

int y));

while

(!q.

empty()

));elseif(

!f[xx]

[yy]

) q.

push

((node));

}}return

(node);}

intmain()

} node ans =

bfs(s1 , s2)

; cout << ans.num <<

' '<< ans.len;

return0;

}

題目描述

如果乙個數a,能由乙個數b 旋轉得到,那麼我們稱為友好數對,如12345 和45123為友好數對,12345 和54321 不為友好數對。

給出兩個正整數l,r,求有多少友好數對,滿足l<=a輸入輸出格式

輸入格式:

第一行乙個整數t,表示資料組數,每組資料兩個正整數l,r。

輸出格式:

對於每組資料,輸出乙個整數表示答案。

輸入輸出樣例

輸入樣例#1: 複製

41 9

10 40

100 500

1111 2222

輸出樣例#1: 複製03

156287

說明對於30%的資料滿足l,r<=1000

對於100%的資料滿足l,r<=2000000,t<=30

這道題的旋轉定義很迷啊…

由題意得,如果a和b互為友好數對,那麼a和b的友好數對也為友好數對,並且這些互為友好數對所組成的集合之間的交集為空,也就是說事實上每個點只會掃瞄一次,因此可以暴力o(n)(好吧,其實還要優化一下,我們預處理10的冪來加快計算速度)

ac code:

#include

#define rg register

#define il inline

#define maxn 5000005

#define ll long long

using

namespace std;

il int

read()

while

(ch >=

'0'&& ch <=

'9')

return x * w;

}bool vis[maxn]

;int p[20]

;int

main()

for(rg int j =

1; j < len ;

++j)

}/*while (x >= 10)

}*/} cout << ans << endl;

}}

題目描述

對於乙個1->n的排列 ,定義a中的乙個位置i是好的,當且僅當ai-1>ai 或者ai+1>ai。對於乙個排列a,假如有不少於k個位置是好的,那麼稱a是乙個好的排列。

現在有q個詢問,每個詢問給定n,k,問有多少排列是好的。答案對10^9+7取模。

輸入輸出格式

輸入格式:

首先輸入q。

接下來輸入q個詢問n,k

輸出格式:

輸出q行,每行乙個整數代表答案。

輸入輸出樣例

輸入樣例#1: 複製

84 3

6 410 7

20 14

50 40

100 72

1000 900

3000 2000

輸出樣例#1: 複製

8448

1433856

868137807

908422882

609421284

150877522

216180189

說明對於20%的資料,n<=10,q=1

對於40%的資料,n<=20,q=1

對於60%的資料,n<=100

對於100%的資料,n,k<=3000,q<=10000

由於這道題的資料範圍,n、k滿足n ^ 2,而q又比較大,我們比較容易想到遞推預處理來o1查詢,但是式子該怎麼推呢?

對於數n和1 ~ n - 1的序列來說,n肯定是比1 ~ n - 1中的any數都要大的,但是不一定它會對答案造成貢獻,我們反向思考一下,因為題目的定義是

對於乙個1->n的排列 ,定義a中的乙個位置i是好的,當且僅當ai-1>ai 或者ai+1>ai

好處我們反而不怎麼好定義,但是壞處就簡單多了,也就是乙個峰大於左右兩邊的數(易證峰不是連續的),現在我們要將n加入到1 ~ n - 1中,試想,如果它加到乙個峰的旁邊,它自己必然是乙個峰,但是原來的峰也必然會消失,導致答案是不變的,如果它不加到峰的旁邊,那麼就多了乙個峰。

推一下式子,我們設f[i][j]為i個數峰為j個的排列數,那麼我們考慮上文的兩種情況:

加到峰的旁邊,不增加峰

f[i][j] += f[i - 1][j](沒有增加峰)* (i - (i - j) << 1 + 2)(若在不是峰的旁邊肯定兩邊都得不是峰)

加到谷的旁邊

f[i][j] += f[i - 1][j - 1] * (i - j) << 1)

ac code:

#include#define rg register

#define il inline

#define maxn 500005

#define ll long long

#define mod 1000000007

using namespace std;

il int read()while (ch >= '0' && ch <= '9') return x * w;}

ll f[3002][3002];

int main()

rg int n , k;

for (rg int i = 1 ; i <= q ; ++i)

ll ans = 0;

for (rg int i = k ; i <= n; ++i)

ans = (ans + f[n][i] % mod) % mod;

printf("%lld\n" , ans);

}return 0;

}

校內集訓(20170903)

題目描述 輸入描述 第一行輸入乙個,表示卡牌數量。第二行輸入乙個由 b g r 組成的長度為的字串,分別表示卡牌的顏色為藍色 綠色 紅色中的一種。輸出描述 輸出 b g r 中的若干個字母,按字典序輸出。代表可能的最後一張牌的顏色。樣例 輸入1輸出1rbg 輸入2輸出2 grgbr 輸入3輸出3 b...

五一校內集訓

day1 語言基礎 int unsigned int等等的區別以及原理 以及溢位的情況 時間複雜度的分析很詳細很詳細 p,np,npc,np hard的區別 自己看的時候leng是沒看懂 常用庫函式的介紹 排序 是否基於比較 試用情況 時間複雜度 資料結構是大部頭 vector list queue...

雅禮集訓 2017 Day2 解題報告

我怎麼知道這種題目都能構造樹形結構。根據高度構造一棵樹,在樹上倍增找到最大的小於約束條件高度的隔板,開乙個 vector 記錄一下,然後對於每個 vector 按照高度排序一下,樹形 dp 即可 code below include define pii pair define mp make pa...