Wenbin's profileWenbin Dai's SpacePhotosBlogLists Tools Help

Blog


    August 31

    Project Euler Problem 37

    Find the sum of all eleven primes that are both truncatable from left to right and right to left.

    DFS搜即可,但是其实搜之前是不确定所有的值一定在Int32的范围内,所以先是用long long 来判断(当然如果有值超出了long long的范围就得用另外的做法了)。从左往右搜,所有的值都只可能由2、3、5、7之一开始,后面的值可以跟1、3、7、9 (其他的数都会制造出合数)。然后一边搜一边判断就可以了。

    /**
     * Problem: Find the sum of all eleven primes that are both truncatable from left to right and right to left.
     * Algorithm: DFS
     * Author: daiwb
     * Date: 2008/08/31
     */
    
    #include <iostream>
    #include <sstream>
    #include <set>
    #include <cmath>
    using namespace std;
    
    #define REP(i,n) for(int i=0;i<(n);++i)
    #define FOR(i,a,b) for(int i=(a);i<=(b);++i)
    typedef long long LL;
    
    int res;
    int num[4] = {1, 3, 7, 9};
    
    int string2int(string str) {
      stringstream ss;
      ss << str;
      int res;
      ss >> res;
      return res;
    }
    
    bool isprime(int val) {
      if (val == 2 || val == 3 || val == 5 || val == 7) return true;
      if (val == 1) return false;
    
      int mid = (int)sqrt(val + 0.5);
      if ((val & 1) == 0) return false;
      for (int i = 3; i <= mid; i += 2) {
        if ((val % i) == 0) return false;
      }
      return true;
    }
    
    bool isok(string str) {
      if (str.length() == 1) return false;
    
      REP(len,str.length()) {
        string s = str.substr(len);
        if (!isprime(string2int(s))) return false;
        s = str.substr(0, len + 1);
        if (!isprime(string2int(s))) return false;
      }
      return true;
    }
    
    void dfs(string str) {
      stringstream ss;
      ss << str;
      int val;
      ss >> val;
      if (!isprime(val)) return;
    
      if (isok(str)) {
        res += val;
      }
    
      REP(i,4) dfs(str + char(num[i] + '0'));
    }
    
    void run() {
      res = 0;
      dfs("2");
      dfs("3");
      dfs("5");
      dfs("7");
      cout << res << endl;
    }
    
    int main() {
      run();
    }

    Project Euler Problem 36

    Find the sum of all numbers less than one million, which are palindromic in base 10 and base 2.

    数据量不是很大(one million以下),暴力做即可。一点小trick就是偶数的二进制表示肯定是类似于1...0,所以必然不是对称的,可以略去。

    /**
     * Problem: Find the sum of all numbers less than one million, which are palindromic in base 10 and base 2.
     * Algorithm: Brute Force
     * Author: daiwb
     * Date: 2008/08/31
     */
    
    #include <iostream>
    #include <sstream>
    using namespace std;
    
    #define REP(i,n) for(int i=0;i<(n);++i)
    #define FOR(i,a,b) for(int i=(a);i<=(b);++i)
    typedef long long LL;
    
    bool isPal(string str) {
      int len = str.length();
      REP(i,len >> 1) {
        if (str[i] != str[len - 1 - i]) return false;
      }
      return true;
    }
    
    bool isPalDec(int val) {
      stringstream ss;
      ss << val;
      string str;
      ss >> str;
      return isPal(str);
    }
    
    bool isPalBin(int val) {
      string str = "";
      do {
        str += char((val & 1) + '0');
        val >>= 1;
      } while (val != 0);
      return isPal(str);
    }
    
    void run() {
      int res = 0;
      for (int i = 1; i < 1000000; i += 2) {
        if (isPalDec(i) && isPalBin(i)) res += i;
      }
      cout << res << endl;
    }
    
    int main() {
      run();
    }

    Project Euler Problem 35

    How many circular primes are there below one million?

    小于one million的数实际上只有6位,而且考虑到大于9的circular prime number只可能包含1、3、7、9 (如果包含0、2、4、5、6、8那么循环过后就会被2或者5整除)。简单的做法就是判断出one million以内所有的数是否为素数(很快,都不用用+2,+4筛法),然后用dfs搜索所有1、3、7、9组成的数加以判断即可。

    /**
     * Problem: How many circular primes are there below one million?
     * Algorithm: DFS
     * Author: daiwb
     * Date: 2008/08/31
     */
    
    #include <iostream>
    #include <sstream>
    using namespace std;
    
    #define REP(i,n) for(int i=0;i<(n);++i)
    #define FOR(i,a,b) for(int i=(a);i<=(b);++i)
    typedef long long LL;
    
    int plist[80000], pcount = 0;
    int mm[1000005];
    
    int prime(int n){
      int i;
      if ((n!=2&&!(n%2))||(n!=3&&!(n%3))||(n!=5&&!(n%5))||(n!=7&&!(n%7)))
        return 0;
      for (i=0;plist[i]*plist[i]<=n;i++)
        if (!(n%plist[i]))
          return 0;
      return n>1;
    }
    
    void initprime(){
      memset(mm, 0, sizeof(mm));
      int i;
      mm[2] = 1;
      for (plist[pcount++]=2,i=3;i<1000000;i++)
        if (prime(i)) {
          plist[pcount++]=i;
          mm[i] = 1;
        }
    }
    
    int res, len;
    int num[4] = {1, 3, 7, 9};
    
    bool isCircularPrime(string str) {
      REP(i,len) {
        stringstream ss;
        ss << str;
        int val;
        ss >> val;
        if (mm[val] == 0) return false;
        str = str.substr(1) + str[0];
      }
      return true;
    }
    
    void dfs(int idx, string str) {
      if (idx == len) {
        if (isCircularPrime(str)) {
          ++res;
          cout << str << endl;
        }
        return;
      }
    
      REP(i,4) {
        dfs(idx + 1, str + char(num[i] + '0'));
      }
    }
    
    void run() {
      res = 0;
    
      // 1-9
      res = 4;
    
      for (len = 2; len <= 6; ++len) {
        dfs(0, "");
      }
    
      cout << res << endl;
    }
    
    int main() {
      initprime();
      run();
    }
    
    August 16

    跌跌撞撞进了GCJ的Regional Final

    GCJ就是一个混血儿,从TopCoder派生来,罚时参照ACM/ICPC,记分参照ACM和IOI,分强弱数据。
     
    总的来说,题目出的还行,类型比较多,很多数学题和几何题,不像TC放眼望去皆DP。但是没有非常明显的送分题,区分度上做得似乎也稍微差点,往往随便做两题简单的就晋级了。
     
    Qualification round
    随便做两题就pass了,不设人数上限。
     
    Round 1
    想不到偶在这里就几乎栽了跟头。每人可以参加三场round 1中的两场,其中一场晋级就ok了。偶的第一场做得奇烂无比,才800多名吧。于是又要参加当天半夜的另一场。结果开赛时偶的笔记本突然挂了。无奈,翻出公司的本本,发现没装Visual Studio。麻烦就麻烦点,那就远程到公司机子上做,结果发现连不上,原来当天清华科技园断电。。。怒了,哥我用Emacs+MingW。但MingW的安装文件下载速度也忒慢了,50m的只有十几二十k的速度。搞来搞去搞到一点,比赛时间也过了一半,想想算了,遂放弃。上网看新闻,结果看到上午的一封Congratulations信,原来Round 1每场前840名晋级,白忙活了-_-
     
    Round 2
    2520->1000,持续低迷,500出头的成绩晋级。
     
    Round 3
    1000->500,开始做的还不错,后来又卡住了。比赛结束512,郁闷而睡。
    结果没想到过了几天又收到Congratulations信,原来前面有选手的source code重新run其他测试数据的时候挂了,偶又升到492了。于是搞了一把复活,进到了Regional Final。-_-
     
    Round 4
    Regional Final,500选手被分到各自所在洲的某个G公司的office。Asian的貌似就去北京的office,就在科技园,两步路-_-要是去Tokyo的多好啊,可以免费玩一趟。Round 4的前100就可以去California的Mountain View参加总决赛。加州还是不错滴,06年去San Diego就玩得不错,期待超常发挥了~

    奥运男篮观战

    托美国同事买的奥运男篮票,14号早上9点的比赛,结果6点就爬起,早早地赶到五棵松篮球馆。
    进场以后发现没吃早饭亏了,因为进来就不能出来,然后场馆里卖的只有简单的饼干、香肠、牛奶什么的,根本吃不饱。好不容易看到有个点卖“满汉全席”方便面,40块一盒,人家还不卖,说是展示云云,我晕-_-
     
    罢罢,咱忍,看球为主。话说五棵松球馆修的也还算不错了,大屏幕、音响啥的都还不错。偶和一干同事都是B类票,坐在上面半场,感觉好高。发现下面半场媒体区占了好大一块,可只满了1/3,真是亏啊,让我坐多好。
     
    第一场西班牙对德国,没啥说的,西班牙实力占优,德国虽然一度领先,最后还是输了十几分。司机一如既往的挫啊,亏得大家那么多掌声。第二场开场仅3分钟,澳大利亚即12:1领先伊朗,宣布垃圾时间提前。偶看得实在郁闷,于是发挥微软勇于挑战的精神,尝试趁乱混入下面半场。没想到志愿者mm眼尖,虽然我只晃了一下就往里冲,还是被人家给看出来是上面的票,踏进场的半只脚又被拉了回来,郁闷-_-
     
    两场结束,我和shaxuan及其同学决定继续留守,看下午中国对安哥拉的比赛。体育馆里在清人,眼看人越来越少,三人决定ws一把。(此处省略500字。。。)
     
    到了下午比赛时间,上面半场果然查得很松,轻松混进场。终于看到中国队啦,姚、易、郅,还有一干小的。毕竟是主场,这场看得比较high,结果也不错,就是第二节又让大家揪心了下,中国队咋老让人这么担心呢。。。Anyway,男篮还是值得看的,起码过一段时间总能给人点惊喜,不像男足,每每看完我都有想吐的感觉。
     
    话说这时候我们仨已经饥饿难当了,下午第二场立陶宛对俄罗斯几乎晕倒在球馆里。。。但其实这场打得最精彩,双方战术素养都不错。尤其是立陶宛,张指导最推崇的“合理”篮球。俄罗斯一帮白人里还有一黑哥们,据说是被AK47拉拢来比赛的,真ws啊。。。不过黑人非常猛,俄罗斯只有两套战术,一是黑人单打得分,而是黑人助攻队友得分。。。但到了后来黑人终于也体会到了啥叫“不怕神一样的对手,就怕*一样的队友”。。。
     
    晚上本还有梦八的比赛,本来还想再ws一把,后来仨人都觉得饿得受不了了,遂出场觅食。球场外听到黄牛报价,普通的C类票都卖4000一张,oh my dog!想想我们只花了170大洋,看了四场,还是很值的。
     
    最后还要祝愿中国队在16号的比赛里搞定德国,小组出线。偶要去沙排作志愿者,就不能在电视机前加油了。。。
    August 11

    拿到奥运门票了

    14号早上西班牙和德国的篮球赛。托美国同事买的票,170米,很值啊。周四打算看看能不能躲过清场看中国和安哥拉的比赛。