1. 程式人生 > >牛客網“程式發生段錯誤,可能是陣列越界,堆疊溢位(比如,遞迴呼叫層數太多)”錯誤的可能原因

牛客網“程式發生段錯誤,可能是陣列越界,堆疊溢位(比如,遞迴呼叫層數太多)”錯誤的可能原因

晚上在牛客網練習程式設計,做了一題網易的,很簡單的題但是會提示“程式發生段錯誤,可能是陣列越界,堆疊溢位(比如,遞迴呼叫層數太多)”,想來想去也不懂為什麼,本地可以測試通過,然後既沒有陣列越界也沒有呼叫遞迴。。。後面找到了原因,有可能是陣列界定太大了,在給陣列賦值的時候系統發生錯誤。

_________________________________________

題目如下:

時間限制:1秒
空間限制:32768K

題目描述
小易有一個長度為N的正整數序列A={A[1], A[2], A[3], …, A[n]}。
牛博士給小易出了一個難題:
對數列A進行重新排列,使數列A滿足所有的A[i]*A[i+1](1<=i<=N-1)都是4的倍數。
小易現在需要判斷一個數列是否可以重排之後滿足牛博士的要求。

輸入描述:
輸入的第一行為數列的個數t(1<=t<=10)
接下來每兩行描述一個數列A,第一行為數列長度n(1<=n<=10^5)
第二行為n個正整數Ai(1<=Ai<=10^9)

輸出描述:
對於每個數列輸出一行表示是否可以滿足牛博士要求,如果可以輸出Yes,否則輸出No

示例1
輸入
2
3
1 10 100
4
1 2 3 4

輸出
Yes
No


_______________________________________________________________

原來的解決程式碼:(個人猜想註釋部分是出錯原因)

#include<iostream>
using namespace std;

int main(){
	
	int n,line,a[10000];	//這裡定義
	cin>>line;
	for(int j = 0 ; j < line ; j++){
		
		cin>>n;
		int countMod4 = 0;
		int countMod2 = 0;
		for(int i = 0; i < n ; i++)
		{		
			cin>>a[i];  //這裡出錯
			if (a[i]%4 == 0)
				countMod4++;
			else if (a[i]%2 == 0)
				countMod2++;
		}
							
		if ((countMod4 >= n/2)||(countMod2 >= n-countMod4*2))
			cout<<"Yes"<<endl;
		else
			cout<<"No"<<endl;
							
	}
			
}


就很簡單的思維,先把數傳進陣列,然後判斷,如果是4的倍數的數比一半(向下取整)多,那肯定是YES,如 _ 4 _ ,(橫線是任意數都可以)。要不然就是2的倍數(非4倍數)的數比總數減去兩倍的4的倍數的數量多,也是可以的。因為一個4的倍數可以佔兩個位置。比如 _ 4 _ 4 _ _ _ (這五個橫線都代表不是4的倍數,只要其中有三個數是2的倍數就可以了,放在最右邊那麼條件就一定成立),比如 _ 4 _ 4 2 2 6 。

————————————————————————————————

嗯。。本地測試是完全沒問題的。。答案也和測試用例一致。。但是提交程式的時候牛客網顯示:

程式發生段錯誤,可能是陣列越界,堆疊溢位(比如,遞迴呼叫層數太多)



我就覺得很奇怪,,按理說我啥也沒幹啊。。後面找到了原因

把a[i]改成x就好了,,想來也是傻了,,其實根本用不到陣列儲存的功能,,直接處理不就行了。。

修改後的程式碼通過所有測試用例,程式正確:

#include<iostream>
using namespace std;

int main(){
	
	int n,line,x;	
	cin>>line;
	for(int j = 0 ; j < line ; j++){
		
		cin>>n;
		int countMod4 = 0;
		int countMod2 = 0;
		for(int i = 0; i < n ; i++)
		{		
			cin>>x;
			if (x%4 == 0)
				countMod4++;
			else if (x%2 == 0)
				countMod2++;
		}
							
		if ((countMod4 >= n/2)||(countMod2 >= n-countMod4*2))
			cout<<"Yes"<<endl;
		else
			cout<<"No"<<endl;
							
	}
			
}
關於這個問題我猜想是牛客網的編譯系統沒辦法處理在陣列索引值較大的時候直接賦值,所以比如當cin>>a[9999]這樣的時候陣列就會發生越界錯誤,但是其實並沒有越界,可能是牛客網編譯系統對於輸入的時候陣列最大的界有範圍限制吧。。

但是如果真的遇到程式設計題需要輸入這麼大的陣列的時候,,就cin>>x; a[i] = x;好了。。。

嗯,,一題這麼簡單的程式設計題浪費了我一小時的時間包括寫部落格的時間。。= =還是太年輕了