import std.stdio, std.conv, std.string, std.bigint; import std.math, std.random, std.datetime; import std.array, std.range, std.algorithm, std.container; string read(){ static string[] ss; while(!ss.length) ss = readln.chomp.split; string res = ss[0]; ss.popFront; return res; } void main(){ int n = read.to!int; int total = read.to!int; int[] as = readln.chomp.split.map!(to!int).array; // そうか… // 半分全列挙にしてたけど、枝刈りをちゃんとやれば単に前からやるだけでいいのか… // (それか後ろからなら割り算で割り切れるという制約がつくのでもっと楽…?) uint[int] xs; xs[as[0]] = 0; foreach(a; as[1 .. n]){ uint[int] xs_new; foreach(k; xs.keys){ if(k + a <= total) if(k + a !in xs_new || xs_new[k + a] > xs[k] * 2 + 0) xs_new[k + a] = xs[k] * 2 + 0; if(k * a <= total) if(k * a !in xs_new || xs_new[k * a] > xs[k] * 2 + 1) xs_new[k * a] = xs[k] * 2 + 1; } xs = xs_new; } debug xs.writeln; if(total in xs){ string ans; foreach_reverse(i; 0 .. n - 1) if((1 << i) & xs[total]) ans ~= "*"; else ans ~= "+"; ans.writeln; } }