大一寒假訓練六(二分查詢) 更新完成

2021-09-08 05:53:11 字數 4204 閱讀 3046

二分查詢最大值的最小值為ans,judge函式中return的時候大於和等於是同一種情況

等於號在judge(m)中,則滿足if(judge(m))時記下ans=m。

#include

using namespace std;

int l,r,n,m,k,ans,a[

10010];

bool judge

(int m)

intmain()

printf

("%d\n"

,ans);}

return0;

}

思路:實數二分,化實數為整數。

實數二分,精度會缺失(如果直接用double二分,最後%.2lf輸出的時候會自動向上取整,可能改變了答案),解決辦法是先把每根繩子長度a[i]乘以100化為整數,再按整數的方法二分,最後輸出答案時再除以100即可。

注意在二分過程中要特判m=0的情況(否則在judge函式中會除以0導致re),m=0時直接break退出二分迴圈,記下答案ans=0。

ac**:

#include

using namespace std;

const

int n=

1e4+10;

double x,ans;

int n,k,l,r,m,a[n]

;bool judge

(int m)

intmain()

l=0,r=

1e7;

while

(l<=r)

//n=1 k=10000 a[1]=1.00時,二分過程中會出現m=0的情況,在judge函式中會除以0導致re

//要防止re,則特判二分過程中m=0直接break,退出二分,記下答案ans=0if(

judge

(m))ans=

1.0*m,l=m+1;

//滿足if(judge(m)),記下ans

else r=m-1;

}printf

("%.2lf\n"

,ans/

100.0);

}return0;

}

二分查詢最大值的最小值為ans,judge函式中return的時候小於和等於是同一種情況

等於號在judge(m)中,則滿足if(judge(m))時記下ans=m。

#include

using namespace std;

const

int n=

1e5+10;

int n,k,t,l,r,ans,a[n]

;bool judge

(int mid)

return num<=k;

}int

main()

//這裡必須要縮小初始區間,如果寫l=0,r=0x3f3f3f3f是錯的

while

(l<=r)

printf

("%d\n"

,ans);}

return0;

}

其實這題和賣古董是同一題,思路是一樣的。

#include

using

namespace std;

const

int n=

1e5+10;

int n,k,l,r,ans,a[n]

;bool

judge

(int mid)

return num<=k;

}int

main()

while

(l<=r)

printf

("%d\n"

,ans)

;return0;

}

先排序,再二分查詢。

#include

using namespace std;

int n,i,l,r,m,cnt,ans,a[

10010];

bool seek

(int l,

int r,

int cmp)

return0;

}int

main()

return0;

}

輸入的時候直接標記每個數的2倍,第二次遍歷的時候如果被標記過則答案+1。

這裡有個玄學的地方,不能把vis標記陣列寫成map形式,否則就超時了。

#include

using

namespace std;

const

int n=

1e4+

10,m=

2e5+10;

int t,x,n,ans,a[n]

,vis[m]

;//不能寫成mapvis; 否則超時

intmain()

return0;

}

二分查詢模板題。

#include

using namespace std;

int n,q,k,i,l,r,m,a[

1000010];

bool judge

(int l,

int r,

int cmp)

return0;

}int

main()

}return0;

}

#include

using namespace std;

double m,y;

doublef(

double x)

double

seek

(double l,

double r)

return m;

}int

main()

可以自己寫二分查詢函式,也可以用stl中的upper_bound函式。

//296ms

#include

using namespace std;

int n,x,i,l,r,m,a[

1000010];

intseek

(int l,

int r,

int cmp)

return r+1;

}int

main()

return0;

}

本題也可以用c++現成的函式!

c++其實有直接求出答案的函式:upper_bound,直接用這個函式比自己寫的二分速度還快一些

upper_bound作用是返回陣列a中第乙個大於x的元素的下標ans,用法是ans=upper_bound(a,a+n,x)-a;

//136ms

#include

using namespace std;

int n,x,i,a[

1000010];

intmain()

return0;

}

這題要特別注意精度:

1、π用acos(-1.0)表示

2、寫原始式v2-v1,如果化簡v2-v1= h * ( p * r * r - r )= h * r * ( p * r * - 1 ),精度會錯

3、實際上還要保留到8位小數而不是4位小數(題目的bug)

#include

using namespace std;

const

double p=

acos(-

1.0)

;//定義π

int t,h;

double

seek

(double l,

double r)

//二分查詢半徑,以下用m表示半徑了

return ans;

//題目要求輸出保留4位小數,但是這裡必須要寫到8位小數的精度(題目的bug)

}int

main()

return0;

}

大一寒假訓練 set

錯誤的刪除操作?上圖的操作會把迭代器刪除!it的指向就空了!於是會出現下圖警示?正確的操作?for it ans.begin it ans.end include using namespace std set int ssr set int iterator it int n,x intmain ...

大一寒假訓練(七)

借鑑二位博主 抱拳 nefu ljw link.nefu wmjlink.problem a 週末舞會 佇列 link.include using namespace std queue int vis1,vis2 intmain return0 problem b 取牌遊戲 佇列 set link...

大一寒假訓練 暴力列舉

其實就是直接迴圈遍歷,利用計算機強大的計算效能,也就是俗稱的 乙個個試 2 5 6題較難 這題需要理清一下思路,然後六重迴圈完事。不超時是因為資料小,資料較多肯定tle.include using namespace std intmain return0 這裡的 是nefu ljw學長的解法,我理...