SRM 464 DIV 2 その2
撃墜された500を清書してみた。
ちょっと書き換えてみたけど結局システムテストで落とされた\(^O^)/
[方針]
n桁の全ての数に対してcolorfulかどうかのチェックをして、
colorfulだった場合カウンターをインクリメントしていって
k番目のcolorfulstringを見つけたらそれを返す。
方針と呼べるたいそうなものではないなぁ。。。全探索っていうのか?
colorfulかどうかのチェックは以下のように行う。
1. 0か1が含まれる場合、colorfulではないのでfalseを返す
2. 同じ数が2つ以上含まれる場合も、colorfulではないのでfalseを返す
3. product valueを格納するset Sを用意する
4. substringのproduct value Pを生成する
5. PがSに含まれればfalseを返す
6. PがSに含まれなければS.insert(P)とする
7. 4に戻る
TLEになっちゃうんだよなぁ。。。
substringの数は最大の8桁の場合でも36個で、8桁の数は全部で10^8-10^7=90000000個だから。。。だめなのか><
#include <cstdio> #include <cstdlib> #include <cmath> #include <climits> #include <cfloat> #include <map> #include <utility> #include <set> #include <iostream> #include <memory> #include <string> #include <vector> #include <algorithm> #include <functional> #include <sstream> #include <complex> #include <stack> #include <queue> using namespace std; static const double EPS = 1e-5; typedef long long ll; class ColorfulStrings { public: bool colorful(int num, int n) { set<int> S; string numstr = int2str(num, n); int used[10]; memset(flag, 0, sizeof(flag)); for (int i = 0; i < n; ++i) { if (numstr[i] == '0' || numstr[i] == '1') return false; // 0か1が含まれればcolorfulではない if (used[numstr[i]-'0'] == 0) used[numstr[i]-'0'] = 1; else return false; } for (int i = 0; i < n; ++i) { for (int j = 0; i+j < n; ++j) { int p = 1; for (int k = i; k <= i+j; ++k) { p *= numstr[k] - '0'; } if (S.find(p) == S.end()) S.insert(p); else return false; // pがすでにあればcolorfulではない } } return true; } /* int -> string変換 */ string int2str(int num, int n) { int keta = 1; string ret = ""; for (int i = 0; i < n-1; ++i) { keta *= 10; } for ( ; keta >= 1; keta/=10) { ret += num / keta + '0'; num %= keta; } return ret; } string getKth(int n, int k) { string result = ""; if (n > 8) return result; // 9桁以上ではcolorfulになりえない if (n == 1) { // 1桁の場合は特殊 if (k >= 1 && k <= 10) { result += (k-1) + '0'; return result; } else { return result; } } int target; // colorfulかどうかチェックを行う数 int goal; // 終点 target = 1; goal = 10; for (int i = 0; i < n-1; ++i) { target *= 10; goal *= 10; } if (k > goal - target) return ""; int cnt = 0; bool flag = false; for ( ; target < goal; ++target) { if (colorful(target, n)) ++cnt; // targetがcolorfulならばcntをインクリメント if (cnt == k) { // k番目のcolorful stringがみつかればループを抜ける flag = true; break; } } if (flag) { result = int2str(target, n); return result; } else return result; } };