(1)說明你的思路
(2)寫出你的算法,可以用語言實現或者用僞代碼表示
個人提示:位圖法
1、這裏用到兩個位圖,先填充第一個位圖a。當發現一個數字被填充過之後,則用這個數字填充b。很明顯,b中記錄的是重複出現過的數字。
2、當掃描完一次之後。再掃描b位圖。只要出現在b位圖中的數,就拿去清除a位圖中的位。最後a中的數字保證是隻出現一次的。
3、最後把a位圖中記錄的數輸出。
值得注意的是:輸出的數可能是負數,爲了處理方便在處理時,統一轉化成爲無符號數,輸出的時候,再轉換成爲負數則可。
你可以先把ms的值改小一些進行測試。由於算法針對的是2.1億的數據量,所以常規的小數據是體現不出優勢的。
當改小ms的值爲100之後,你輸入的值需要位於1~99之間。(如果不改MS的值,那麼代碼爲正解)
#include <stdio.h>
#include <stdlib.h>
#define BITSPERWORD 32
#define SHIFT 5
#define MASK 0x1F
const unsigned long long ms = 4294967295;
int a[134217728];
int b[134217728];
void set(int *a, unsigned int i) { a[i>>SHIFT] |= (1<<(i & MASK)); }
void clr(int *b, unsigned int i) { a[i>>SHIFT] &= ~(1<<(i & MASK)); }
int test(int *a, unsigned int i){ return a[i>>SHIFT] & (1<<(i & MASK)); }
int main()
{
int n;
unsigned int x;
unsigned long long i;
while (scanf("%d", &n) != EOF){
x = n;
if (test(a, x) == 0) set(a, x);
else set(b, x);
}
for (i = 0; i < ms; ++i){
x = i;
if (test(b, x)) clr(a, x);
}
for (i = 0; i < ms; ++i){
x = i;
if (test(a, x)) printf("%d\n", (int)x);
}
return 0;
}