偽文法基礎 輸入輸出練習2__位元運算

來源:互聯網
上載者:User

時間限制 : 10000 MS 空間限制 : 2200 KB 問題描述

給你n個整數,裡面有很多重複的數。其中只有一個數出現了3k+1次,其他都是3的倍數次。現在要你找出這個數。 輸入格式

第一行一個整數n。
第二行n個整數。 輸出格式

一個正整數,出現3k+1次的那個數。 範例輸入1

7
2 7 4 2 7 2 7 範例輸出1

4 範例輸入2

10
7 8 8 7 7 8 2 8 2 2 範例輸出2

8 提示

1<=n<=10^6,顯然n是一個3k+1型的數
0<=每個數<=10^18
注意記憶體限制。 題解

題目本身很水,隨便開個map什麼的就可過,然而本題記憶體限制只有2M……
回憶一個經典的例題,一個數列中只有一個數出現了奇數次,其他數都出現了偶數次,求這個出現奇數次的數。比較經典的做法是使用位元運算中的異或運算,把所有數異或起來,所得的數就是答案。這個演算法的實質是將每個數二進位化,一個數出現多少次其每一位的1就出現多少次,再結合異或運算的性質,便得解了。類比這種思想,我們開三個變數 a0,a1,a2 a 0 , a 1 , a 2 a_0,a_1,a_2分別記錄出現次數模3為0,1,2的二進位位有那些,那麼加入一個數 x x x可得轉移(其他幾個類似): a0=(a0 xor (a0 and x)) or (a2 and x) a 0 = ( a 0   x o r   ( a 0   a n d   x ) )   o r   ( a 2   a n d   x ) a_0=(a_0\ xor\ (a_0\ and\ x))\ or\ (a_2\ and\ x)依次加入數列中的每一個數就得解了。本題也用到了類似狀態壓縮的思想,也說明 二進位可離線處理一些數字出現次數的問題

代碼

#include<stdio.h>using namespace std;typedef long long ll;ll n,x,a0,a1,a2,t0,t1,t2;int main(){    scanf("%lld",&n),a0=(1ll<<62)-1;    while(n--)    {        scanf("%lld",&x);        t0=(a0^(a0&x))|(a2&x);        t1=(a1^(a1&x))|(a0&x);        t2=(a2^(a2&x))|(a1&x);        a0=t0,a1=t1,a2=t2;    }    printf("%lld\n",a1);    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.