突然心血來潮,想總結乙個筆記,奈何老劉上課實在是沒講什麼東西,所以我在這裡同時插入對我自己的看法
/—警戒線----均為自己整理仿冒必究-----警戒線—/
度娘上給出的列舉的準確說法是這樣的:
「列舉法,常常稱之為窮舉法,是指從可能的集合中一一枚舉各個元素,用題目給定的約束條件判定哪些是無用的,哪些是有用的。能使命題成立者,即為問題的解。」
實際上,列舉可以很簡單,例如,讓你找出1-100裡面的偶數,那麼就必須得從1-100中找。
#include
using
namespace std;
intmain()
rt 0
;}
這就是乙個簡單的列舉。
那麼。我們可以很清晰的看出,列舉的優點有著直觀性的特點,並且這個演算法「肯定是對的」。易於驗證。
那麼,我們再看乙個列舉的例子。
百錢買百雞的問題我相信大家都已經非常熟悉了。它的核心**如果只靠列舉,那麼就是這樣的。
for
(int i=
1;i<=
100;i=i+1)
for(
int j=
0;j<=
100;j=j+1)
for(
int k=
0;k<=
100;k=k+3)
if(..
....
....
......)
這個三重迴圈實際上就是很難受的。我們看,這三個迴圈裡面這個if()要執行100x100x100次。也就是100w次。十分驚悚,因為如果雞的總數超過1000只,程式會直接boom的超時。
所以,我們也可以很清晰的看出,列舉的缺點是運算量大,解題效率低。
----------------------分割線-------------------------------
列舉的難點就是需要我們在不同的情況要在列舉中插入不同的優化以提公升時間效率。畢竟全部tle是乙個非常瘋狂的事情。
給你n根火柴棍,你可以拼出多少個形如「a+b=c」的等式?等式中的a、b、c是用火柴棍拼出的整數(若該數非零,則最高位不能是0)。用火柴棍拼數字0-9的拼法如圖所示:
注意:1.加號與等號各自需要兩根火柴棍
2.如果a≠b,則a+b=c與b+a=c視為不同的等式(a,b,c>=0)
3.n(n<=24)根火柴棍必須全部用上
這道題就是典型的列舉題。這裡說一下老劉的方法(簡稱老劉法):
老劉法就是先預處理火柴的情況然後再進行對火柴的列舉。
先開乙個存放所有棍子的陣列
int stick[
99000]=
;
預處理怎麼辦呢?我們對其進行找規律:「1」=2 「11」=「1」+「1」=4 「111」=「11」+「1」=6 「1111」=「111」+"1」=8。
不難總結出一點,stick[i/10]+stick[i%10]。
那麼,題中給出的n是小於等於24的,如果全部考慮,那麼最多可以擺出四位數的火柴(即1111),那麼我們就列舉到1111.
for
(int a=
0;a<=
1111
;a++
)for
(int b=
0;b<=
1111
;b++
)
而且。還得注意等號和加號都是算在內的,所以可以預處理n。即
int n;
cin>>n;n-=
4;
題目描述
給你乙個整數n和長度l, 現在要求你找x個連續的非負整數,使得它們的和是n, 同時要滿足 x >= l, 你的任務是使得x最小,輸出這連續的x個整數。
如果找不到這樣的連續整數或者能找到但x > 100, 那麼你輸出-1。 也就是能找到滿足題意的連續整數,且x < =100時,才輸出這連續的x個非負整數。
輸入格式
一行:兩個整數: n 、l. 1 <= n <=10^9, 2 <= l <= 100.
輸出格式
如果找到合法的連續整數,把它們從小到大輸出,每行乙個整數。 否則輸出-1。
input: 18 2
output:56
7這道題要用到等差數列的通項公式
sum=(首項+末項)×項數÷2;設首項為x,最小的長度為len。末項即為 x+len-1
則 (x+x+len-1)len /2 =sum
化簡,2x= 2*sum/ len -len +1
then you can find the x!!
對於這道題,無非就是乙個推導加乙個判斷。
for
(int i=l;i<=
100;i++
)}
這裡是如果找到合法的連續整數,把它們從小到大輸出。也不用sort(),因為已經可以排好了。
剩下的情況直接輸出-1即可。
題目描述
給定n個數,求這n(1 <=n <= 100,000) 個數的某個連續子串行的累加和,保證這個連續子串行的累加和最大。
輸入格式
第一行:乙個整數n。(1 <=n <= 100,000) 接下來n行,每行乙個整數p_i(-1,000 <= p_i <= 1,000)。表示第i個數。
輸出格式
乙個整數,表示子串行的最大連續累加和。
樣例資料
input7-3
49-2-58-3
output
4這道題方法非常多。光列舉其實就可以用3種方法。也可以直觀的看出優化的作用和列舉的缺點。
採用三重迴圈列舉起點位置,終點位置及其子段和,比較,求最大值,核心**如下
int a[
10000];
int maxsum;
//最大值
int temp;
//子段和
maxsum=a[i]
;for
(int i=
1;i<=n;i++
)//起始位置
for(
int j=i;j<=n;j++
)//終點位置
2.通過預處理的方式優化一下第一種方法,丘處第一位置到每個位置的和a[i],然後a[i]+a[i-1]值即為當前位置值,減少了求和運算,對於子段的子段和就是a[j]-a[i].只需要二重迴圈,**不再給出。
3.「老劉演算法」(常梓良極力推薦!)
可以這麼想一下,就是當前數+正數》當前數,當前數+負數《當前數
如果當前累加和為負數,會讓後邊累加和變小。反之,會讓後邊累加和變大
那麼我們只需要讀入資料。接著一重迴圈列舉第1個數到第n個數,求出以當前數結尾的最大欄位和t,如果t>ans,那麼賦給ans。
最後,輸出ans即可。
int sum=0;
ans=
-100000000
;for
(int i=
1;i<=n;i++
)
列舉與模擬
我是一名新手程式設計師,今天來為比我還新手的人講解一下 列舉與模擬 一.什麼是列舉與模擬 二.試題講解 int ball 3000 for int i 10 i 2222 i ball i ball i 10 ball i 10 這裡火柴棒我們用 ball 來表示 純屬不知火柴棒的英語 這裡我們將每...
2023年7月8日 列舉與位列舉
1.列舉型別是用於宣告一組命名的常數的基本資料型別 2.所有列舉型別都隱式的繼承system.enum型別 system.enum型別是繼承自system.valuetype型別唯一不為值型別的引用型別 3.compareto 將此例項與指定物件進行比較並返回乙個對二者的相對值的指示 4.equal...
7月13日模擬賽總結
lgtb與偶數 考慮到連續的一段奇偶性相同的數字才能被刪除,所以直接貪心即可,用棧實現lgtb與序列 考慮到ai最多變成58,如果變成更大的數還不如變成1,而且58之內只有16個素數 並且可以證明對於兩個數a b,變成的數a b 所以最多只有16個最大的數變成素數,其他的數都會變成1 所以直接對於前...