1. 程式人生 > >轉載!!ACM Tips #1

轉載!!ACM Tips #1

ACM Tips #1

為什麼不能有輸入提示

以上次講過的a+b problem為例,可能會有同學會想給一些人性化設計,於是就添加了輸入提示:

#include <cstdio>

int main()
{
	int a, b;
	printf("Please input two integer: \n");
	while(scanf("%d%d", &a, &b) != EOF)
	{
		printf("%d\n", a+b);
	}
	return 0;
}

顯然,結果會返回Wrong Answer。那這是為什麼呢?

事實上評測系統並不會care你的人性化設計,它只關心你的程式碼的輸出跟標準輸出是否一字不差

而顯然,這個程式碼給出的輸出在評測系統看來就是錯的。

我們假設這麼一個輸入:

1 1
1 2

那麼標準答案會是:

2
3

而上述程式碼給出的輸出是:

Please input two integer: 
2
3

評測姬一看,哦豁,你這多出一行,WA了,走好不送。

所以不要試圖加入任何人性化設計,包括額外的輸出以及system("pause")之類的語句都不需要加入,因為你面對的並不是人,而是鐵面無私的評測姬。

上次漏掉的一種會導致RE的情況

我們假設有這麼一道題目:第一行輸入正整數n,第二行輸入n個正整數,你需要輸出他們的和。

給個樣例吧:

Input:

4
1 3 2 5

Output:

11

題目的資料範圍為,n<=1000,結果保證在int範圍內。

首先,對於這種題目,目前看來大家都傾向於開一個長度為n的動態陣列。

但是可以注意到,極端情況下陣列大小也只有1000,那為何不一開始就開個長度為1000的陣列呢?

畢竟開動態陣列還是比較麻煩的一件事,能用靜態最好就是用靜態。

好的,於是有些同學悟到了,開始順手寫了程式碼:

#include <cstdio>

int main()
{
	int a[1000], n;
	scanf("%d", &n);
	for(int i = 0; i < n; i++)
	{
        scanf("%d", &a[i]);
	}
	
	int sum = 0;
	for(int i = 0; i < n; i++)
	{
        sum += a[i];
	}
	printf("%d\n", sum);
    return 0;
}

測試一波,覺得自己很穩,一交,RE了

為什麼呢?事實上也並不是所有情況都會RE,但是有時候它就是給你RE了。

事實上這種RE是陣列訪問越界導致的RE。也就是說,假設陣列大小1000,你訪問到a[1000],它就可能給你RE了。

事實上有時候a[1000]是可以訪問的,但是那裡是沒有初始化的未知空間,甚至裡面存的可能是你所使用的另一個變數,這個時候就可能出現數據亂搞然後導致WA

那麼為什麼會訪問越界呢?這個原因比較玄學以及事實上我也不清楚(這個真的超出我的知識範圍了orz)

所以一般情況下,保險起見,開陣列的時候會多開幾個位置。也就是說,假設我們需要大小為1000的陣列,那麼我會這麼開:

int a[1005];	// 習慣多開五個,也有人開十個或兩個的

這僅僅是一種保險措施,但多開幾個又不會少塊肉,不是嗎。

一些需要你們自己查或者自己試的知識

總覺得啥都給你們講明白就沒意思了,畢竟對ACM來說自學能力是十分重要的一環。

所以這裡會留給一些東西給你們自己去查一查。以後如果還有更新的話,需要自學的知識佔比重會越來越多。

ASCII碼

你們可以自學一下ASCII碼,如果能理解以下幾個點就差不多了

  • 字元其實也是數字
    • 更高階點,字元其實也可以用於計算
  • 5並不等於'5'
    • 也就是說,想用if(c == 5)來判斷字元變數c的值是否為字元5是不行的

string

這個不同於c語言的string.h,而是C++的string。它屬於STL中容器的一員。學會使用它你們就可以在大部分時候擺脫字元陣列了。

那麼同樣給出幾個點:

  • 明白string可以像intchar那樣用
  • string怎麼輸入,怎麼輸出
  • string也可以像字元陣列那樣操作(下標之類的)
  • 試著用string+號拼接字串

sort

不用再自己寫氣泡排序了!C++有現成的排序可供使用!而且比氣泡排序快!

那麼同樣給出幾點:

  • 要用sort需要#include<algorithm>using namespace std;
  • 掌握sort的用法,並試著用sort重寫第一次訓練的第五題

時間複雜度

這是一個十分重要的概念,學會它之後你們就掌握瞭如何預估一個程式會跑多久,這在演算法競賽中是十分重要的(至少它會避免你在一個註定為TLE的演算法上耗太多時間和精力)

同樣給出幾點:

  • 評測姬一秒差不多會做10的9次方次簡單計算(或者簡單步驟)
  • 瞭解大O標記法
  • 氣泡排序的時間複雜度是?
  • 氣泡排序為什麼會比sort慢呢?