1. 程式人生 > >到底A多少題才能不被大佬按在地上摩擦

到底A多少題才能不被大佬按在地上摩擦

2018年第43屆ACM/ICPC亞洲區域賽瀋陽站現場賽

  這次比賽賽前,有訊息稱這次比賽的難度是div1,比賽前心裡沒底。因為自己的學校實力不強,所以這次現場賽資格也來之不易,這是我第一次也是我最後一次打ICPC,所以我不想留下遺憾。

  拿到題目的時候也有點畏懼,因為這次比賽的題目普遍性的都很長,而且是全英文的。為了防止漫無目的的讀題而影響做題時間,我們決定跟榜。很快有大佬隊過了J題,J題題面有整整一面,硬著頭皮上吧。很快讀完題就發現,這題是個模擬題。

####Problem J. How Much Memory Your Code Is Using?

/*題意*/
	給出一行C語言語句,求宣告變數所佔用的位元組數,宣告的變數或者陣列只能有一個。
/*解題思路*/
	直接暴力即可。

  由於不熟悉Linux作業系統下的程式設計環境,隊友在寫這個程式的時候也遇到了很多問題,比如字串輸入沒有gets和getline函式,無奈,只能用getchar進行輸入了。寫程式的速度還算快,草草寫完測了幾組樣例,感覺沒問題就提交了,結果不盡如人意,Wrong Answer了。然後我們馬上找到了一組錯誤樣例,改了程式,又重新測試了幾組樣例,這次應該沒問題了,提交上去還是Wrong Answer,心態瞬間崩了。我說乾脆直接用%s輸入吧,對於變數型別直接判斷首字母就行了,long long和long double另作判斷。然後隊友又重新寫了份程式碼,跑了先前測試的樣例,然後提交上去,隨後我們就看到了correct原諒色的反饋結果,心態終於正了正。此時我們不敢看排名,因為有兩次罰時,名次肯定在老遠。

  時間已過去將近一個小時。隨後有大佬隊開了C題,我們馬上轉戰C題。在讀懂題意之後,我們感覺這就是個規律題。

Problem C. Insertion Sort

/*題意*/
	現有一段函式,要求輸入一個數組A和一個k,進行一次題目給出的氣泡排序(題目名叫插入排序,過程是冒泡。。),進行k次。
	題目的意思是,給你三個數,n,k,mod,問你在1-n的全排列中,有多少個序列執行這個函式之後其最長上升子序列的長度大於等於(n-1),最後的結果對mod取模。1<=n,k<=50,1e8<=mod<=1e9。
	給出程式
	function Insertionsort(A,k)
  		n←the length of A
  		i←1
  		while i<=n and i<=k do
          	j←i
          	while j>1 and A[j-1]>A[j] do
            	t←A[j]
            	A[j]←A[j-1]
            	A[j-1]←t
            	j←j-1
          	end while
          	i←i+1
      	end while
	end function
/*解題思路*/
	樣例給的是4 1,4 2,4 3,4 4(省略mod)的,note也比較貼心,把4 1的情況的排列全部列舉出來了,觀察了一番,並沒有找到什麼規律。果斷寫全排列和LIS暴力一下,由於10的全排列就很多了,所以我們打了1 1到8 8表,這一列出來我就發現了規律。分別以n和k為兩維,構建了一個矩陣。
     1     1     1     1     1     1     1     1
     2     2     2     2     2     2     2     2
     5     6     6     6     6     6     6     6
    10    14    24    24    24    24    24    24
    17    26    54   120   120   120   120   120
    26    42    96   264   720   720   720   720
    37    62   150   456  1560  5040  5040  5040
    50    86   216   696  2640 10800 40320 40320
	縱座標是n,橫座標是k。
	很明顯就能看出當n>=k的時候,結果全為n!。對於k>=n這種情況,直接輸出n!。然後我們討論剩下的情況,對於每一列我們求出差分序列。
	 1
     3     4
     5     8    18
     7    12    30    96
     9    16    42   144   600
    11    20    54   192   840  4320
    13    24    66   240  1080  5760 35280
   	對於每一列,差分序列構成了一個等差數列,哇!當時我發現這個規律的時候是真的開心。然後我又發現,對於每個序列的,其首項是i*i!,然後差是2*i!,驗證:對於第四行,96 144 192 240,96=4*4!,144-96=2*4!。由於這個這個題的n和k很小,但是數值很大,而且模數不定,不能一開始就把所有結果打表。我們可以先找出(n,k)這種情況,然後遞推下去,直到求出答案。

  程式碼寫的飛快,樣例測了也沒問題,就直接提交了。本以為這題應該能1A,可是又反回了Runtime Error,當時真的是眼前一黑,哪裡越界了?鼓起勇氣看了下排名,已經掉到100+了,瞬間新涼了半截。突然隊友說了句,woc!輸入還有個t,然後加了個t的輸入,光速提交,本以為這次穩了,結果又是Wrong Answer。規律錯了?規律錯了?規律錯了?我規律找錯了?我問,題目中有沒有n<k這種情況?隊友又說,woc!我沒寫n<k這種情況!然後他加上這種情況後,提交上去,Correct!又看了一眼rank,我們到43名了,但是在兩題尾,這時已經過去兩個小時,離比賽結束還有三小時。繼續開題。

  隨後看到了G題,感覺能寫,題目給了12s的限時。

####Problem G. Best ACMer solves the Hardest Problem

/*題意*/
	在一個二維空間內,開始給出n個點,和每個點的w值,接下來有m個操作,一共有四種操作,增刪改查。然後讓輸出給次查詢結果。查詢的時候會給出一個k值和(x,y),如果有點跟他的歐幾里得距離等於sqrt(k),那麼就加上其w值,最後輸出和。對於每次操作有個lastans,真正的座標是(((x+lastans)%6000+1),((y+lastans)%6000+1))。0<=k<=1e7,1<=x,y,w<=6000,1<=n,m<=1e5。
/*解題思路*/
	由於0<=k<=1e7,所以我們可以完全可以把1-1e7所有平方數和拆分出來。也沒有多少,最多才3000多。然後就直接暴力,這樣複雜度是大概有1e8,12s限時。

  按照這種思路,我們寫了程式,交上去就TLE了,一直懷疑是方法錯了,然後就一直在嘗試這一題直到比賽結束。後來問了北航的大佬,他們也是這樣寫的,但是他們在維護整個圖的狀態的時候,用的是map!我透!因為這題有1e5的運算元,STL想都沒想,就用了鄰接矩陣儲存。因為平時的訓練預設STL很笨重。真的很可惜。這題出了我們應該就有銀了,不過事已至此,見好就收吧。

  封榜的時候,我們隊排名即將掉出100名,比賽是114名之前有獎。最後幾分鐘的時候由於一直在懟G題,而且沒過就很絕望。比賽最終還是結束了,滾榜是真的刺激。從最後一名一名一名往上滾,開始放出來的是封榜之前的排名,以及封榜後的提交記錄,但是看不見結果,主持人一名一名檢視結果,出了題就跑到上面去了。當看到滾到130名的時候,心想這個獎就穩了。最終我們是銅獎,馬馬虎虎吧。頒獎結束後,我們就去中街那邊吃大餐了。

  至此,我的ACM生涯結束了。