題目背景
於大夫建造了乙個美麗的池塘,用來讓自己愉快的玩耍。這個長方形的池子被分割成了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...