Time of Update: 2018-12-03
判斷兩個double型是否相等,不能用判斷int型的方法去比較,這也是對初學者容易出現的錯誤,剛開始我在做POJ1730那個題目時候,就犯了這樣的毛病。做出來的答案總是錯的。因為我用double a,double b,if(a==b)...這樣就是錯的,後來在網上看了別人的代碼才知道,比較兩個double型:fabs(a-b)<=eps,(eps=1e-9),eps的值是起到精確度的作用。這大概是用到了極限的思想了。對POJ1730的題目,是要我們求a^b=c;求滿足該等式下,b的最大值。
Time of Update: 2018-12-03
剛學並查集,這題還TLE幾次了。關鍵是沒最佳化。代碼:#include<stdio.h>#define N 10000001int father[N];int sum[N];int find(int x){return x==father[x]?x:find(father[x]);}int main(){int t,max,n,m,i;while(scanf("%d",&t)!=EOF){for(i=1;i<=N;i++){ father[i]=i;
Time of Update: 2018-12-03
這道題是類比加法的,沒什麼難度。#include<stdio.h>#include<string.h>char st1[1005],st2[1005];int st3[2005];void Add(){int i1=strlen(st1)-1,i2=strlen(st2)-1;int carry=0,tmp,i,j=0; for(;i1>=0&&i2>=0;--i1,--i2,++j){tmp=st1[i1]-'0'+st2[i2]-'0
Time of Update: 2018-12-03
集合A-B的意思是,元素在A且不在B中。這道題顯然不是什麼難題。個人水平有限,我喜歡分析這樣的水題,這對我個人來講,有助於培養思維能力,再難的題也是有簡單的題複合在一起組成的。這題有兩種方法,一是直接枚舉,而是二分尋找。顯然枚舉只對小數有可以,時間複雜度為(n^2)而二分尋找先要排序,後尋找,時間複雜度為2nlogn,顯然我們會採用第二中方法。輸入n,m代表集合A,B元素的個數,接下來是集合A的元素和集合B的元素。輸出A-B,若沒有元素,就輸出NULL。如果是第一種:代碼如下.0(n^2)#in
Time of Update: 2018-12-03
點擊開啟連結用漢字寫的題目,不容小視。這題要很好的空間想象力,開了一個五維數組dp[k][x][y][xx][yy],表示把對角線為(x,y)-(xx,yy)的矩形分割成k塊能獲得的最小值。先看問題,要我們求方差;如果不化解,有點無從下手.可以為S^2=(1/n)∑xi^2+x^2, (xi表示每個矩形的權值,x
Time of Update: 2018-12-03
這題是遞迴加類比。用L[i]表示i個步伐向左走走的次數,用R[i]表示。。。想右走走的次數。f[i].....總共的方案次數。 向左走 L[i]=L[i-1]+f[i-1] R[i]=R[i-1]+f[i-1] f[i]=f[i-1]+L[i-1]+R[i-1] 參考代碼:#include<stdio.h>int main(){int t,n;int L[21],R[21],f[21];L[0]=R[0]=f[
Time of Update: 2018-12-03
題目串連分析:此題我糾結很久,寫不出動態方程,看神人代碼以後,用一個三位元組dp[i,j,k],表示從第i個到第j個可以消去的方塊個數所能獲得的最大值。那麼就有:dp[i][j][k]=dp[i][r-1][0]+(len[r]+k)^2; len[r]是表示第從r個有連續相同的個數。代碼;#include<stdio.h>#include<cstring>#define Max(a,b) a>b?a:b;#define N 205bool vis[N];int
Time of Update: 2018-12-03
中文題,題意不用解釋了。分析: 用dp[i][j] 表示i個物品分成j組的最小代價。(這個很關鍵)做dp題第一步就是,用一個dp數組表示相應問題的含義。這個做好了,寫狀態方程就容易一些。根據題意: 當 i==2*j狀態方程為: dp[i][j]=dp[i-1][j]+(a[i]-a[i-1])^2
Time of Update: 2018-12-03
題目串連中文字,題意就不必過多解釋。也許是以前做了最長上升子序列,感覺這題有點類似。這不是二維的嗎,其實這題不然。這條路徑可以轉彎,可以想到用搜尋。單獨的搜尋還不夠,我們必須要用儲存每個位置的最長路徑,這樣只要找出最大的就可以了,所以這可以用dp+DFS實現了。代碼:#include<cstdio>#include<cstring>#include<queue>#define max(a,b) a>b?a:busing namespace
Time of Update: 2018-12-03
這題的思路很簡單,只要連續相加的和大於或等於零,就一直加下去,如果在第i-1項小於零,把sum的值賦值為第i個序列的值。並記錄它的下標,就可以了。#include<stdio.h>#define N -10000000int main(){ int t,n,j,k,beg,end,cas=1;long sum,max;int a[100001];scanf("%d",&t); while(t--){scanf("%d",&n);for(int i=1;i&
Time of Update: 2018-12-03
Yefeng自從學了ACM之後就和人說他能快速的定一個正整數數是否為素數,後來大家猜他大概只知道判定10^18以內的數。於是都想的拿非常大的數來問他。當然對於非常大的數Yefeng自己也是沒辦法在短時間內計算出來的。還好Yefeng學過素數定理,知道越是大的數,這個數是素數的機率就越低,於是他就故意告訴大家一個數,並附上一句話,這個數是你給的數一個因子,所以你給的數是一個合數。聰明的你能想個方法判定戳穿Yefeng的謊言嗎?若干組測試資料,每組測試資料兩行,第一行是Yefeng要判定的數a(10
Time of Update: 2018-12-03
啊!這題本來很簡單,就是不細心,搞的我wa五六次啊,嚴重受到打擊啊!多重背包轉化成01背包和完全背包就可以了。這個題,是說能分成開不,那麼兩個人所擁有的價值是總價值的一半。把背包的容量剛好看成總價的的一半v(本來可以看成無限大)但沒必要,因為它剛好用v的體積。那麼就是,在容量為v的條件下,看能否把背封裝滿。這樣就可以用多重背包實現了。#include<stdio.h>#include<string.h>#define
Time of Update: 2018-12-03
一條直線能夠將平面分成2部分,兩條直線能夠將平面分成4部分,而對於一條“V”型線而言,平面被分成2部分,兩條“V”型線最多能夠將平面分成7部分。對於橢圓封閉曲線對平面的劃分又將不一樣,任意兩個橢圓至多有兩個交點。現在給定一個N,你能夠計算出三種不同情況下,空間最多被劃分出多少個部分嗎?若干組測試資料,每組測試資料佔一行,每行一個正整數N(1<=N<=10^6)每組資料輸出一行,每行3個整數,之間用空格隔開。分別輸出N條直線,N條“V”型線,和N個橢圓最多能夠將平面劃分成多少部分,結果
Time of Update: 2018-12-03
題意:去掉連續的數,使得它們的總和mod一個數不變。分析:模(m)一個數不變,在某些連續數字會存在能被m整除。除掉這些數,對餘數是沒任何影響的。故可以轉化為:在n個數中,取出連續的的數使得它們的和能被m整除,求最多可以去多小個。這題和最大連續子序類似。於是設有:s[i]表示前i個數的總和。那麼,要求得的是:(s[j]-s[i-1])%m==0 的條件下。求j-i+1的最大值(i到j相隔最遠)。根據同餘定理就有:s[j]%m-s[i-1]%m==0;cord:#include<cstdio&
Time of Update: 2018-12-03
題意:有N個頂點,每個頂點有一個權值,初始值皆為0。接下來有M次操作,操作內容為 [a,b) or [b,a),將區間內頂點i 權值置為1,求最後頂點權值為0的數量。多組測試資料。第一行為兩個整數n, m,n(1<=n<=20000)表示頂點, m(1<=m<=50000)表示操作次數。接下來包含m行,每行包含兩個正整數 a,b屬於區間[1,n] ,意義如上所述。每組測試輸出一行,包含一個整數,表示頂點值為0的數量。輸入 3 1 1 2 3 1 1 3 輸出 2 1分析:
Time of Update: 2018-12-03
點擊開啟連結總是把問題看的太複雜,還以為是三分尋找。這題根本沒這個必要。只要使圓周剛好與邊相等就行了,矩形中最大的圓就是取最小邊作為直徑就行了。再分別以兩邊為高,比較就行了。水啊!代碼:#include<stdio.h>#include<math.h>#include<algorithm>using namespace std;const double pi=acos(-1.0);int main(){ double
Time of Update: 2018-12-03
其實我也不太瞭解這個這個威佐夫博弈,定理的證明也沒去過多的瞭解,只知道,它是一個數列,表示在這兩個數一組的一種情況,如,(1,2),(3,5),(4,7).....中表示了先取的敗局,可以用一個黃金分割點來刻畫。具體要認懂,去看別人的分析吧,對於學習編程的人,沒必要去個個弄懂,這麼多理論,要弄懂,並非易事,我們只要知道有這麼一回事就行了,怎麼用代碼去實現它,就ok了。#include<stdio.h>#include<math.h>int main(){ int
Time of Update: 2018-12-03
題意:對簡單的‘+’,‘-’,‘*’,‘/';進行運算,運算的結果保證在長整型範圍內。對除以0的輸出"impossible".輸入的運算操作均合法。輸入的字串長度小於50,數值沒有小數出現。本題的意圖很明顯,就是依靠列隊來或堆棧來實現。規定了一些條件,從而大大地降低了難度。分析也很容易。比如算:2+3*5-2;對於合法的運算操作,我們可以知道,運算元比操作符多一個,並且是相互交替,奇偶相間。而運算優先順序‘*’和‘/‘高一些。在入列的時候我就直接算出來。也可以全部加進去,在以後出來,方法就是:在
Time of Update: 2018-12-03
基礎題。用來增強信心。代碼:#include<stdio.h>int father[1005];int find(int x){return x==father[x]?x:find(father[x]);}int main(){int t,a,b,n,m,ans,i;scanf("%d",&t);while(t--){ans=0;scanf("%d%d",&a,&b);for(i=1;i<=a;i++) father[i]=i;while(b--){
Time of Update: 2018-12-03
首先聲明:本題分析來自他人,不屬本人創作。題目分析: 根據題意可知,題目要求的是求(x+k*m)modl=(y+k*n)mod l這個模方程的k的最小整數解;跟據模的性質對這個方程變形得:k*(m-n)+t*l=y-x(t為引進的一整數);令a=(m-n);b=y-x;得: k*a+t*l=b;