読者です 読者をやめる 読者になる 読者になる

Tamflexの貯蔵庫

やる気のない備忘録

【python】pythonで変数名を取得する

python3 python

ラムダ式で書いてみた

var_name = lambda val : [k for k, v in globals().items() if id(v) == id(val)]
a = 1
s = var_name(a)[0]

【c++11】warning: deleting object of polymorphic class type ‘Derived’ which has non-virtual destructor might cause undefined behaviour [-Wdelete-non-virtual-dtor]

modern c++

自作クラスでdeleteでデストラクタを呼ぼうとしたら以下のような警告が出た。

warning: deleting object of polymorphic class type ‘Derived’ which has non-virtual destructor might cause undefined behaviour [-Wdelete-non-virtual-dtor]
delete v;

ここに対処方法が書いてあった。

またここに警告の意味が書いてあった。
VerboseDiagnostics - GCC Wiki

どうやら基底クラスか派生クラスのどちらかのデストラクタを仮想化すれば解決するらしい。
すなわち

class Base {
 ~Base(); // Non-virtual destructor.
};

class Derived : public Base {
 virtual ~Derived(); // Virtual destructor.
};

とするか

class Base {
 virtual ~Base();
};

class Derived : public Base {
 ~Derived();
};

とすれば解決する。

テンプレートクラスTの内部クラスを呼び出す

modern c++

共通の内部クラスを持っている複数のクラスをつくって、テンプレートからそれを呼び出したいことがあるかもしれません。その時は以下のように書けばうまく動くでしょう。

#include <iostream>

using namespace std;

class A1
{
public:
  struct Param
  {
    Param(){cout << "A1" << endl;};
    void print(){cout << "Hello" << endl;};
  };
};

class A2
{
public:
  struct Param
  {
    Param(){cout << "A2" << endl;};
    void print(){cout << "World" << endl;};
  };
};

template <class T>
class B
{
private:
  typedef typename T::Param TParam;
  TParam* x;
public:
  B()
  {
    x = new TParam;
    x->print();
  };
};

int main()
{
  B<A1>* b1;
  b1 = new B<A1>;
  B<A2>* b2;
  b2 = new B<A2>;
  return 0;
}

それぞれ同じParamというクラスをもったA1,A2というクラスを候補とするテンプレートクラスBを作る状況です。
この時 typename T::Paramという型の変数を使うことができます。

循環少数のプログラム

c

フロイドの循環検出法 - Wikipedia
これを使うらしい

int f(int n)
{
  int p = 1, q = 1;
  int s = 0, t = 0; // start : s, goal : t
  while(1)
  {
    p = (p*10)%n;
    q = (q*10)%n;
    q = (q*10)%n;
    if(p==q) break;
  }
  if(p!=0)
  {
    q = 1;
    s = 1;
    while(p!=q)
    {
      s++;
      p = (p*10)%n;
      q = (q*10)%n;
    }
    q = (q*10)%n;
    t = s;
    while(p!=q)
    {
      t++;
      q = (q*10)%n;
    }
  }
  return t-s+1;
}

aoj 0503

Aizu Online Judge modern c++

少し考えれば一番下のものを順番に移動していくしかないことがわかります。
置く場所を#0,#1,#2としてgoalを#0に固定する。1〜nまでのコップが順に並んだものが

  • #0にあるとき

=> 0

  • #1にあるとき

=> 3^n

  • #2にあるとき

=> 2*3^n
したがって下のコードのように再帰でかけるでしょう。あとはコップの配置をbitで表して右シフトで一番小さいコップから順に処理すればよいでしょう。

int p[20];

int f(int a, int b, int c)
{
  if(!b&&!c) return 0;
  int s = (a|b|c)>>1;
  int t = 0;
  while(s&1) {t++;s>>=1;}
  if(1&a) return f(a>>1,b>>1,c>>1);
  if(1&b) return f(c>>1,b>>1,a>>1)+p[t];
  if(1&c) return f(a>>1,b>>1,c>>1)+2*p[t];
}

int main()
{
  int n,m;
  p[0] = 1;
  FOR(i,1,20)
  {
    p[i] = p[i-1]*3;
  }
  while(cin >> n >> m,n)
  {
    int a[3] = {0};
    REP(i,3)
    {
      int t,u; cin >> t;
      REP(j,t)
      {
        cin >> u;
        a[i] |= 1 << u-1;
      }
    }
    int ans = min(f(a[0],a[1],a[2]),f(a[2],a[1],a[0]));
    cout << (ans>m?-1:ans) << endl;
  }
}