2018提高組模擬9(未完)
2018提高組模擬9
—————————————————————————————————————————20181004
T1
K進位制
(WOJ4036)
【模擬||數論】
描述
給定一個K(2<=K<=16)進位制數a,判斷a是否能被K-1整除。
輸入
第一行是一個整數t(1<=t<=50),表示測試點數量。
對於每組資料,第一行一個整數K,表示進位制。
第二行一個K進位制數,表示a。保證a是合法的K進位制數,沒有前導0,且只由’0’-‘9’、’A’-‘F’構成。
輸出
如果a可以被K-1整除,輸出”yes”,否則輸出”no”。
樣例輸入
2 16 2D 10 19
樣例輸出
yes no
提示
對於40%的資料,a的長度不超過5。
對於100%的資料,a的長度不超過100000。
題解
像十進位制的除法的豎式一樣模擬就好了
當然還有一種神奇做法:
#include<iostream> #include<cstring> #include<cmath> #include<cstdio> using namespace std; int t,k; char c[100010]; void solve(){ int len=strlen(c+1),now=0; for(int i=1;i<=len;++i){ now*=k; if(isdigit(c[i]))now+=(c[i]^48); else now+=(c[i]-'A'+10); now%=(k-1); } if(!now)printf("yes\n"); else printf("no\n"); } int main(){ scanf("%d",&t); while(t--){ scanf("%d",&k); scanf("%s",c+1); solve(); } return 0; }
T2
(WOJ4037)
排隊
描述
在成都某中學有m個男生與n個女生排隊,這個學校的女生比較古怪,從某個位置(包含這個位置)開始往前數,男生的數量超過了女生的數量,女生會感覺不安全,於是會大叫起來,為了構建和諧校園,安排隊伍時應該避免這樣的情況。請你計算出不會引發尖叫的排隊方案的概率。(排隊方案不同定義:當且僅當某個某個位置人不一樣,如男生A、男生B ,與男生B、男生A ,2個排列是不同方案)
輸入
第一行1個整數, 表示測試資料的組數。
每個資料 有兩個數 N,M(N個女生,M個男生)
輸出
對於每組資料,輸出一個實數(保留到小數點後 6 位)
樣例輸入
3 1 0 0 1 1 1
樣例輸出
1.000000 0.000000 0.500000
提示
【 Hint】
第一組:只有一個女生,一種方案且可行
第二組:只有1個男生,一種方案且不行
第三組:兩種方案 女、男可行,男、女不可行,可行概率0.5
【資料規模】
30%的資料: (測試組數<=10),(0<=N,M<=1000).
100%的資料: (測試組數=9008 ), ( 0<=N,M<=20000 ).
題解
數學找規律
先打一個暴利程式,然後小資料輸入看結果,很有規律的!!
暴力程式:
#include<cstdio>
#include<iostream>
using namespace std;
inline int read(){
int x=0;char c=getchar();
while(!isdigit(c))c=getchar();
while(isdigit(c)){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
return x;
}
int t,a,b;
int dfs(int now,int g,int bo){
if(bo>g)return 0;
if(now>a+b)return 1;
int ans=0;
if(g<a)ans+=dfs(now+1,g+1,bo);
if(bo<b)ans+=dfs(now+1,g,bo+1);
return ans;
}
int bb(int x){
if(x==1)return 1;
if(x<1)return 1;
return x*bb(x-1);
}
int main(){
t=read();
while(t--){
a=read();b=read();// 女 男
if(b>a){
printf("0.000000\n");
continue;
}
printf("%lf\n",1ll*dfs(1,0,0)*bb(a)*bb(b)*1.000000/bb(a+b));
}
return 0;
}
正解(轉換方式很多)
可以將原問題轉化一下,看成是在一個二維平面上行走,女生看成移動(1,0),男生看成移動(0,1),
那麼到達(N,M)點且路線又不走到y=x 這條直線上方的路線總數就是答案,
這個組合問題很經典,方案數為 C(M+N,M)-(M+N,M-1),所以可以知道答案就是1-M/(N+1)
#include<cstdio>
#include<iostream>
using namespace std;
inline int read(){
int x=0;char c=getchar();
while(!isdigit(c))c=getchar();
while(isdigit(c)){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
return x;
}
int t,a,b;
int main(){
t=read();
while(t--){
a=read();b=read();// 女 男
if(b>a||(b==0&&a==0)){
printf("0.000000\n");
continue;
}
printf("%.6lf\n",(double)(a-b+1)/(double)(a+1));
}
return 0;
}
T3
(WOJ4038)
(tarjan無向圖邊雙連通分量+樹形DP)
航班
描述
L因為業務繁忙,經常會到處出差。因為他是航空公司的優質客戶,於是某個航空公司給了他一個優惠券。
他可以利用這個優惠券在任何一個國家內的任意城市間免費旅行,當他的路線跨國才會產生費用。L有一個航空公司的價格表與航線。而且每個城市出發都能到所有的城市,2個城市間可能有不止一個航班,一個國家內的2個城市間一定有不同的路線,但是不同國家的城市間只有一條路線。L想知道從每個城市出發到產生費用最多的城市,不過你不能重複在一個航班上飛來飛去產生費用,必須沿最少的費用路線飛行
輸入
第一行,兩個整數 N,M,表示N 個城市, M 條航線。
接下來 M 行,每行三個整數 a,b,c,表示城市 a,b 之間有一條費用為 c 的航線。
輸出
共 N 行,第 i 行為從城市 i 出發到達每個城市額外費用的最大值。
樣例輸入
6 6 1 4 2 1 2 6 2 5 3 2 3 7 6 3 4 3 1 8
樣例輸出
4 4 4 6 7 7
提示
【解釋】
有四個國家,包含的城市分別為 {1,2,3},{4},{5},{6}。
從城市 1 出發到達城市 6,乘坐(1,3)(3,6)兩個航班費用最大,(1,3)在國內為免費航班, (3,6)的費用為 4,所以從 1 出發的最大費用為 4。
【資料規模】
對於 40%的資料 1<=N<=1000,1<=M<=1000
對於 100%的資料 1<=N<=20000,1<=M<=200000
題解
先用無向圖邊雙連通分量縮點,再用一個樹形DP就好了
方案一:
兩次dfs/樹形dp求直徑的2個端點A,B,
則 x到最遠距離的距離是 MAX(dis(x,A),dis(x,B))
方案二:
樹形DP換根法
記錄每一個點向下的最大值與次大值
對於每一個點,需求的最大答案就是:
從父親走到自己的兄弟,或從父親走到自己的祖父,或由自己走到自己的兒孫
………………………………