查看: 2337|回復: 0
打印 上一主題 下一主題

[GCJ] 2014 1A A - Charging Chaos

[複製鏈接]
  • TA的每日心情
    開心
    2015-4-12 10:09
  • 簽到天數: 137 天

    [LV.7]常住居民III

    142

    主題

    686

    帖子

    3559

    積分

    邁向天堂

    蘇多門

    Rank: 8Rank: 8

    積分
    3559

    新手達陣台南一中資訊社程式設計達人 - 2014

    跳轉到指定樓層
    樓主
    發表於 2014-5-15 17:54:41 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式

    趕快加入我們來參與討論吧!

    您需要 登錄 才可以下載或查看,沒有帳號?加入我們

    x
    本帖最後由 domen111 於 2014-6-2 16:32 編輯

    Google Code Jam 2014年 Round 1A
    原題(英文): https://code.google.com/codejam/contest/2984486/dashboard#s=p0
    TOJ(中文,輸出有一點不同): http://toj.twbbs.org/oj/pro/4/

    題意:
    有N個插座和電器產品,每個電器產品和插座用長度為L的0與1表示,必須同樣才能配對,你可以做一個操作:切換所有插座的指定位元,請問你最小操作數。

    範例測資:
    Input
    Output
    3
    3 2
    01 11 10
    11 00 10
    2 3
    101 111
    010 001
    2 2
    01 10
    10 01
    Case #1: 1
    Case #2: NOT POSSIBLE
    Case #3: 0

    範例測資說明:
    Case #1:
    切換第二個位元,變成: 00 10 11

    解法:
    小冊資可以暴力解,不過比賽時我寫出一堆bug,花了2個多小時才AC
    正解:
    參考: http://puzzlersworld.com/interview-questions/google-code-jam/charging-chaos-solution-google-codejam/


    用XOR做出表格計算兩個電器產品對電源需要切換的部分,找找看要切換哪個。
    由上圖紅色文字可知要用"01"去切換,這代表第一個位元不用切換(0),第二個位元要切換(1)。

    AC code:
    #include<iostream>
  • #include<bitset>
  • #include<set>
  • #include<algorithm>
  • using namespace std;
  • int T,n,l;
  • long long ou[150],de[150];
  • int count1(long long num)
  • {
  •         int ans=0;
  •         while(num!=0)
  •         {
  •                 if(num&1)ans++;
  •                 num>>=1;
  •         }
  •         return ans;
  • }
  • bool check(long long data)
  • {
  •         long long ouc[150],dec[150];
  •         for(int i=0;i<n;i++)
  •         {
  •                 ouc[i]=ou[i]^data;
  •                 dec[i]=de[i];
  •         }
  •         sort(ouc,ouc+n);
  •         sort(dec,dec+n);
  •         for(int i=0;i<n;i++)
  •                 if(ouc[i]!=dec[i])
  •                         return 0;
  •         return 1;
  • }
  • long long readBits()
  • {
  •         string s;
  •         cin>>s;
  •         long long ans=0;
  •         for(int i=0;i<s.size();i++)
  •                 ans<<=1,ans+=s[i]-'0';
  •         return ans;
  • }
  • int main()
  • {
  •         cin>>T;
  •         for(int no=1;no<=T;no++)
  •         {
  •                 cin>>n>>l;
  •                 set<long long> ta;
  •                 for(int i=0;i<n;i++)
  •                         ou[i]=readBits();
  •                 for(int i=0;i<n;i++)
  •                         de[i]=readBits();
  •                 for(int i=0;i<n;i++)
  •                         for(int j=0;j<n;j++)
  •                                 ta.insert(ou[i]^de[j]);
  •                 set<long long>::iterator iter;
  •                 int best=100000;
  •                 for(iter=ta.begin();iter!=ta.end();iter++)
  •                 {
  •                         if(check(*iter))
  •                                 best=min(count1(*iter),best);
  •                 }
  •                 if(best==100000)
  •                         printf("Case #%d: NOT POSSIBLE\n",no);
  •                 else
  •                         printf("Case #%d: %d\n",no,best);
  •         }
  • }



  • 評分

    參與人數 1金幣 +3 收起 理由
    Sylveon + 3

    查看全部評分

    蘇多門 domen111
    My Web: https://sites.google.com/site/domenprg/
    回復

    使用道具 檢舉

    您需要登錄後才可以回帖 登入 | 加入我們

    本版積分規則

    快速回覆 返回頂部 返回列表