c++のキャストとか

openbabelがC++で書かれているので、今年はC++を覚えようと。

int a = (int)('0'); // 48

これはpythonでいうord

>>> ord("0")
48

で、最初よく分からなかったのでこれ。

(char)(5 + '0'); // 5

結局

int a = 5 + '0'; // 53

となっているからint + charみたいなのもよろしくやっといてくれるっちゅう理解でいいのかな。

とりあえずクックブックでも買うべきか。

ProductName C++実践プログラミング
スティーブ オウアルライン
オライリージャパン / ¥ 6,090 ()
在庫あり。

ProductName C++クックブック
D. Ryan Stephens,Christopher Diggins,Jonathan Turkanis,Jeff Cogswell
オライリー・ジャパン / ¥ 4,515 ()
在庫あり。

SRM162-DIV2-250

最小と最大の数を与えられた時にそのレンジの数の最小公倍数を求める。

順繰りにかけていって、その際に最大公約数で割ってく。最大公約数はユークリッドの互除法で。

def lcm(first,last):
    l =1  
    for i in range(first,last):
        l = l * i / gcd(l,i)
    return l 

def gcd(a,b):
    if(b==0): return a
    return gcd(b, a % b)

print lcm(1,5)
print lcm(4,5)
print lcm(1,12)

実行

/usr/bin/python  /Users/kzfm/python/lcmr.py 
12
4
27720

c++のcout

ちょっと確認

#include <iostream>

using namespace std;

int main(){
  const char* a = "abcde";
  cout << a <<endl;

  cout << *a <<endl;
  cout << *++a <<endl;
  cout << *++(++a) <<endl;

}

実行する。

$ ./test
abcde
a
b

ふむ、なるほど。

今日のtopcoder

今日のtopcoder

pythonと同じ感覚で、ベキ乗を計算するのに

 results += 2 ** i

とかやってたみたいで、コンパイル時に

invalid type argument of 'unary *'

というエラーが出てきてたのだけど、型か?キャストか?なんてドはまりしたあげく時間を食いつぶして死亡。

c++ のc_strとconst

string型にc_strメンバ関数を適用するとcharのconst char 配列のアドレスが得られる

#include <string>
#include <iostream>

using namespace std;

int ccount(const char* a){
  int r = 0;
  while(*a){
    ++r;
    ++a;
  }
  return r;
}

int main(){
  string  test_str = "test";
  int count = ccount(test_str.c_str());
  cout << count << endl;
}

whlile(*a)と書くところはわかるんだけど、引数にconst charでないとだめな理由がわからん。const charとcharって違う型なのか?単にconstっていうキーワードがついてるだけなんだと思ってた。

ProductName ロベールのC++入門講座
ロベール
毎日コミュニケーションズ / ¥ 3,990 ()
通常24時間以内に発送

あと、typedefの使い方もなんとなくわかった。mapとか省略したくなる。

c++でset (SRM-DIV2-250)

ユーザー登録する際にIDがかぶったら数字のナンバリングをする

setの使い方を覚えた。

class UserName {
public:
  string newMember(vector <string> existingNames, string newName) {
    int n=1;
    set <string> s;
    for(int i=0;i<existingNames.size();++i){
      s.insert(existingNames[i]);
    }

    if(s.count(newName) == 0) return newName; 

    while(1){
      stringstream ss;
      ss << newName << n;
      if(s.count(ss.str()) == 0) return ss.str();
      n++;
    }
};

set便利

SRM414

一問も解けなかった。というか250点に時間をかけすぎたうえに途中であきらめたのがよくなかった。

RestaurantManager

席が埋まっているかどうかを、何番目のグループがどの席に座っているかという情報をmapで持たせようとしてたのが間違い。単にどの席がいつまで埋まっているかという時間の情報をベクタに突っ込んでおいて新規客の到着時刻と照らし合わせればよいだけだった。

class RestaurantManager {
public:
  int allocateTables(vector <int> tables, vector <int> groupSizes, vector <int> arrivals, vector <int> departures) {
    vector <int> occupied;
    int away = 0,j;
    sort(tables.begin(),tables.end());
    for(int i=0;i<tables.size();++i) occupied.push_back(0);

    for(int i = 0;i<groupSizes.size();++i){
      for(j = 0;j<tables.size();++j){
        if(groupSizes[i] <= tables[j] && occupied[j] <= arrivals[i]){
          occupied[j] = departures[i];
          break;
        }
      }
      if(j == tables.size()) away += groupSizes[i];
   }
   return away;
  }
};

Embassy

あとで

SRM200-DIV2-1000

WindowManager

class WindowManager {
public:
  vector <string> screen(int height, int width, vector <string> windows) {
    vector <string> result;
    stringstream ss;
    int lx,ly,rx,ry;
    char c;
    result.clear();
    string s;
    s.clear();
    s = "";
    //    cout << width << "," << height << endl;
    for(int a=0;a<width;++a) s += " ";
    for(int b=0;b<height;++b) result.push_back(s);

    for(int i = 0;i<windows.size();++i) {
      ss.str(windows[i]);
      ss >> ly >> lx >> ry >> rx >> c;
      rx += lx -1;
      ry += ly -1;

      for(int y=0;y<height;++y) {
    for(int x=0;x<width;++x) {
      if((x==lx && y==ly) ||(x==lx && y==ry) ||(x==rx && y==ly) ||(x==rx && y==ry)) {
        result[y][x] = '+';
      }
      else if(((x == lx)||(x == rx)) && (y > ly) && (y < ry)) {
        result[y][x] = '|';
      }
      else if(((y == ly)||(y == ry)) && (x >lx) && (x < rx)) {
        result[y][x] = '-';
      }
      else if((x >lx) && (x < rx) && (y > ly) && (y < ry)){
        result[y][x] = c;
      }
        }
      }
      ss.str("");
      ss.clear();
    }
    return result;
  } 
};

SRM199-DIV2-500

三角形の数を数える

パズルみたいな問題。上向きと下向きに分けて数えていけばOK

class TriangleCount {
public:
  int count(int N) {
    int result = 0;
    for(int i = 1;i<=N;++i){
      for (int j = i;j<=N;j++){
    result += j-i+1;
    int down = j - i + 1 -i;
    if ((down) > 0) result += down; 
      }
    }
    return result;
  }
};

SRM198-DIV2-500

赤と黒のチェッカーボードの赤い部分を数える

チェッカーボードの作り方がおかしいのに気づかず、テストがこける理由が分からなかった。

class RedSquare {
public:
  int countTheEmptyReds(int maxRank, int maxFile, vector <int> rank, vector <int> file) {
    int board[50][50];
    int result = 0;
    memset(board,0,sizeof(board));
    bool black;
    for(int   i=0; i<maxRank;++i) {
      if     (i == 0) {black  = true;}
      else if(board[i-1][maxFile-1]){black = true;}
      else {black = false;}
      for(int j=maxFile-1; j>=0; --j) {
    if(black){
      black = false;    
        }
        else{
          board[i][j] = 1;
          black = true;
        }
      }
    }

    for(int k=0;k<rank.size();++k) {
      int m = rank[k]-1;
      int n = file[k]-1;
      board[m][n] = 0;
    }

    for(int x = 0;x<maxRank;++x)
      for(int y = 0;y<maxFile;++y) 
result += board[x][y];

    return result;  
}
};