デジタルコンテンツエキスポ2011に行ってきた


大学や企業がこぞって夢のある技術やアイデアを発表・展示するイベント
「デジタルコンテンツエキスポ2011」に行ってきました。

やっぱり最近のトレンドが顕著に出ていて、
3D技術 と Kinect を題材にしたものが多かったです。
目新しい技術、意外性のあるアイデアの数々。
実用化が楽しみです。

では、いつものようにpdfでレポをどうぞ。
DIGITAL CONTENTS EXPO .pdf

EPOCH予選の解き方公開

プログラミングコンテスト EPOCH@まつやま の予選が終わりましたね。
稚拙ながら 私の解き方を公開しようと思います。

大雑把な考え方はこちらのpdfにまとめました↓
EPOCH@まつやま予選 .pdf
何でこんな図を書いたのかって?
プログラムを書くのにフローチャートは要らないと気付けるのは、フローチャートを書いてからですね。
コーディング前に考えをまとめるには別の手法が必要でした。

さてソースコード↓
1問目
[cpp]#include
#include
#include
using namespace std;
void main(){
// 変数用意
int l; //汎用カウンタ
int tmp1; //汎用一時データ
int tmp2;
int inputed; //入力された値
int b = 0; //重複する中で最大値
int quantityOfData; //データの個数
vector::iterator itr; //汎用イテレータカウンタ

// データ個数の取得
cin >> quantityOfData;
vector data( quantityOfData ); // 配列用意

// データの取得
for( l=0 ; l < quantityOfData ; ++l ){ cin >> inputed;
data.at( l ) = inputed;
}

// データをソート
sort( data.begin() , data.begin() + quantityOfData );

// 重複の除去
for( int l=1 ; l < quantityOfData ; ){
tmp1 = data.at(l-1);
tmp2 = data.at(l);
if( tmp1 == tmp2 ){
itr = data.begin() + l;
data.erase( itr-1 , itr+1 ); //重複を除去
quantityOfData -= 2;
b = tmp1; //グループBの最大値の記録(最後に見つかった重複が最大)
}
else if( tmp1 == b ){
itr = data.begin() + l;
data.erase( itr-1 ); // 3重以上に重なる場合
quantityOfData -= 1;
}
else
++l;
}

// b番目に大きい(下からb番目)を取り出す
if( b < quantityOfData )
cout << data.at( quantityOfData – b ) << endl;
else
cout << *(data.begin()) << endl;
}[/cpp]

2問目
[cpp]#include <string.h>
#include <vector>
#include <stdlib.h>
#include <iostream>
using namespace std;
#define MIN_DISTANCE_DEFAULT 3 // minDistanceのデフォルト値
#define WORD_LENGTH_MAX 255 // 与えられる文字列の文字数の最大値
#define WORD_LINE_MAX 100000 // 与えられる文字の行数の最大値
#define ADDED 1 // 追加:1点
#define DELETED -1 // 削除:-1点
#define CHANGED 2 // 変更:2点
#define EQUAL 3 // 同一:2倍
#define NO_RELATION -2 // 無関係:点数初期化
static vector< vector<int> > d( WORD_LENGTH_MAX , vector<int>(WORD_LENGTH_MAX) ); // レーベンシュタイン距離計算用テーブル

//最小の数を探す
int min(int a, int b, int c)
{
return a > b ? (b > c ? c : b) : (a > c ? c : a);
}

//レーベンシュタイン距離を求める
//ただし2以上が確定した地点でreturnし2を返す。
//3以上にならないという保証はない。
char levenshteinDistance(const string& str1, const string& str2)
{
int lenstr1 = str1.size() + 1;
int lenstr2 = str2.size() + 1;
static int distance; // 求めたレーベンシュタイン距離
static int minDistance; // dの形成する表のある1行の中での最小値
int i1 = 0, i2 = 0, cost = 0;

for (;i1 < lenstr1; i1++) d[i1][0] = i1;
for (;i2 < lenstr2; i2++) d[0][i2] = i2;

for (i1 = 1; i1 < lenstr1; i1++) {
minDistance = MIN_DISTANCE_DEFAULT;
for (i2 = 1; i2 < lenstr2; i2++) {
cost = str1[i1 – 1] == str2[i2 – 1] ? 0 : 1;
distance = min(d[i1 – 1][i2] + 1, d[i1][i2 – 1] + 1, d[i1 – 1][i2 – 1] + cost);
d[i1][i2] = distance;
if( minDistance > distance ) minDistance = distance; // 最小値の更新
}
if( minDistance > 2 ) return 2; // 2以上の確定
}

return d[lenstr1 – 1][lenstr2 – 1];
}

// 行われた操作の調査
char analyzeOperation( const string& str1 , const string& str2 ){
static char distance;
distance = levenshteinDistance( str1 , str2 );

// 距離0
if( distance == 0 )
return EQUAL;

// 距離1
int strLength[2] = { str1.size() , str2.size() };
if( distance == 1 && strLength[0] == strLength[1] )
return CHANGED;
else if( distance == 1 && strLength[0] == ( strLength[1] + 1 ) )
return DELETED;
else if( distance == 1 && strLength[0] == ( strLength[1] -1 ) )
return ADDED;
// 距離2
else if( distance == 2 ){
return NO_RELATION;
}
cout << "ERROR_DISTANCE_ONE_IS_STRANGE" << endl;
exit( -1 );
}

// メイン関数
void main(){
// 変数用意
vector<string> data(WORD_LINE_MAX); // 受け取ったデータの蓄積
long long point = 0; // 得点
int calcStartPoint = 0; // 計算開始点
int i; // 汎用カウンタ
char inputed[WORD_LENGTH_MAX]; // 受け取った文字列
char operation; // 文字列操作
vector<int> operationData; // 操作集
int N; // 受け取る文字列の行数
cin >> N;
operationData.reserve( WORD_LINE_MAX );

// データの受け取り
for( i = 0 ; i < N ; ++i ){
cin >> inputed;
data.at(i) = inputed;
}

// 第1走査:計算開始点の探索(得点計算を行わない)
for( i = N-1 ; i >= 1 ; –i ){
operation = analyzeOperation( data[ i-1 ] , data[ i ] );
if( operation == NO_RELATION ){ // 得点が0になるのでそれ以前を考慮しない
break;
}
operationData.push_back( operation ); // ついでに操作データの取得
}

// 第2走査:得点計算
for( i = operationData.size()-1 ; i >= 0 ; –i ){
operation = operationData.at(i);
if( operation >= DELETED && operation <= CHANGED ) // DELETED , ADDED , CHANGED のいずれか
point += operation;
if( operation == EQUAL )
point *= 2;
}

// 結果出力
cout << point << endl;
}[/cpp]

3問目
先頭の0を考慮するのを忘れました。予選落ち\(^o^)/
[cpp]#include <string>
#include <iostream>
#define LINE_LENGTH_MAX 999
using namespace std;
static int i; // 汎用カウンタ
static int t; // 汎用一時変数

// 引数のうち大きい方を返す
int higher( const int& a , const int& b ){
return a >= b ? a : b;
}

// 足し算が正しいか判定
// ( 与えられた1行の数字 , + 区切りの右に来る数字の位置(添え字) , = 区切りの(ry
bool isCorrectPlus( const string& lineData , const int& plusStart, const int& rightStart ){

// 変数用意
int operand1Length = plusStart;
int operand2Length = rightStart – plusStart;
int rightLength = lineData.length() – rightStart;
string operand1; // 文字分割1
string operand2; // 文字分割2
string right; // 文字分割3
char carry = 0; // 繰り上がり
char plus; // 1桁を足した結果
int op1 , op2; // 1行単位のオペランド

// 分割代入
operand1 = lineData.substr( 0 , operand1Length );
operand2 = lineData.substr( plusStart , operand2Length );
right = lineData.substr( rightStart , rightLength );

// operand1の桁数がoperand2の桁数以上になるように入れ替え
if ( operand1Length < operand2Length ){
t = operand1Length;
operand1Length = operand2Length;
operand2Length = t;
operand1.swap( operand2 );
}

// 計算
for ( i=1 ; i <= operand1Length ; ++i ){
op1 = operand1[ operand1Length – i ];
op2 = i <= operand2Length ? operand2[ operand2Length – i ] : ‘0’;
plus = op1 + op2 + carry – ‘0’;
if( plus > ‘9’ ){
plus -= 10;
carry = 1;
}
else
carry = 0;
if ( plus != right[ rightLength – i ] )/*{cout << "CALC" ;*/ return false;//}
}

// ループを抜けた後、最後のcarryで場合分け
if ( carry == 1 && operand1Length != rightLength -1 ) return false;
if ( carry == 1 && operand1Length == rightLength – 1 ){
if( right[0] != ‘1’ ) return false;}
if ( carry == 0 && operand1Length != rightLength ) return false;

return true;
}

// 数字列1行から数式が成り立つか検証
bool checkLine( const string& lineData ){

// 変数準備
int plusStart = 1; // 区切り1 (区切りの右側の文字の添え字)
int rightStart; // 区切り2
int lineDataLength = lineData.length(); // 文字数

// 区切り組み合わせ総当たり
for ( ; plusStart < lineDataLength – 1 ; ++plusStart ){
for( rightStart = plusStart + 1 ; rightStart < lineDataLength ; ++rightStart ){
// 事前チェック
// 明らかに桁数が違う場合計算をとばす
int operand1Length = plusStart;
int operand2Length = rightStart – plusStart;
int rightLength = lineDataLength – rightStart;
int figureGap = rightLength – higher( operand1Length , operand2Length );
if ( figureGap < 0 || figureGap > 1 ) continue;

// 計算する
if( isCorrectPlus( lineData , plusStart , rightStart ) == true ){
return true;
}
}
}
return false;
}

void main(){

// 変数準備
int ans = 0; // 解答となるカウンタ
int N; // 与えられるデータ数
string lineData; // 与えられたデータ1行の内容
int i; // 汎用カウンタ
cin >> N; // データ数の読み込み
lineData.reserve( LINE_LENGTH_MAX );

// 数える
for( i = 0 ; i < N ; ++i ){
cin >> lineData;
if (checkLine( lineData ) == true ) ++ans;
}

// 出力
cout << ans << endl;[/cpp]

ニコファーレ体験会に行ってきた

10月1日、ニコファーレ体験会に行ってきました。

簡単に内容を説明しましょう。2部に分かれてて、
第1部は内覧会。
ステージの上に立ったり調整室、控室などを見たり、その他説明など。
第2部は体験会。
実際に公式生放送を発信し、コメントが壁面LED上を流れるなどニコファーレの本領発揮。
放送内容は、会場に来た人がニコ動上の動画をリクエスト→ニコファーレで動画再生→その様子を配信
といった流れです。

たった500円の入場料で全面LEDの迫力が体験できるんですよ!
さすが綺麗なPVがよく映える。
流れるコメントで一体感もでるし、良い感じ。
しかし、綺麗な動画があまりリクエストされなかった点が問題です。
ネットを通して7万人が注目した、最新鋭の機材が映し出す映像。
そこで何故卑猥なのやら耐久系やらをリクエストする人が出てくるか。
生放送はほとんどギャグ配信と化してました。
「それでこそニコニコだ」と言う人も多かったのでまぁ、 そんなもんか。

そんな体験会の様子をいつものようにpdfにまとめてみたの
ご覧あれ↓
ニコファーレ体験会
 .pdf