dility Lesson5 - GenomicRangeQuery
39238 ワード
コード#コード#
初めての試み
時間の複雑さ:O(N*M)->タイムアウト
// you can use includes, for example:
// #include <algorithm>
#include <string>
// you can write to stdout for debugging purposes, e.g.
// cout << "this is a debug message" << endl;
vector<int> solution(string &S, vector<int> &P, vector<int> &Q) {
// write your code in C++14 (g++ 6.2.0)
vector<int> answer;
int memo[27] ={0,};
memo['A'-'A'] = 1;
memo['C'-'A'] = 2;
memo['G'-'A'] = 3;
memo['T'-'A'] = 4;
for(int i=0;i<P.size();i++) {
string str = S.substr(P[i],Q[i]-P[i]+1);
int min = 999;
for(int j=0;j<str.length();j++) {
min = min > str[j]-'A' ? str[j]-'A' : min;
}
answer.push_back(memo[min]);
}
return answer;
}
タイムアウトが予想されていましたが、試した解答です.中间のmemo[27]はif
4つのドアが书きたくないだけで书かれたコード...ほほほ論理は
substr
を用いて遺伝的に区分され、for
ゲートを迂回してmin
を比較しただけである.やっぱりタイムアウト二次試行
時間の複雑さ:O(N+M)->合格しましたが、テストケースはフィルタリングできなかったようです.
// you can use includes, for example:
// #include <algorithm>
#include <string>
// you can write to stdout for debugging purposes, e.g.
// cout << "this is a debug message" << endl;
vector<int> solution(string &S, vector<int> &P, vector<int> &Q) {
// write your code in C++14 (g++ 6.2.0)
vector<int> answer;
vector<vector<int>> memo;
vector<int> A, C, G, T;
for(int i=0;i<S.length();i++) {
if(S[i] == 'A') {
A.push_back(i);
} else if(S[i] == 'C') {
C.push_back(i);
} else if(S[i] == 'G') {
G.push_back(i);
} else if(S[i] == 'T') {
T.push_back(i);
}
}
memo.push_back(A);
memo.push_back(C);
memo.push_back(G);
memo.push_back(T);
for(int i=0;i<P.size();i++) {
for(int j=0;j<4;j++) {
bool flag = false;
for(int k=0;k<memo[j].size();k++) {
if(memo[j][k] >= P[i] && memo[j][k] <= Q[i])
{
flag = true;
answer.push_back(j+1);
break;
}
}
if(flag) break;
}
}
return answer;
}
ACGT
のindex
を保存し、A -> C -> G -> T
の順にfor
がドアの周りに存在し、answer
に入れてbreak
を行う.合格しましたが、
AAAAAAAAAAAA~T
このように最後がT、P, Q
が最後の文字を指す場合、P.size()xS.length()なのでO(N*M)は合格できないかもしれませんが、このようなテストケースはないようです.3回目の試み
O(N+M)かもしれません.
// you can use includes, for example:
// #include <algorithm>
// you can write to stdout for debugging purposes, e.g.
// cout << "this is a debug message" << endl;
vector<int> solution(string &S, vector<int> &P, vector<int> &Q) {
// write your code in C++14 (g++ 6.2.0)
vector<int> answer;
int path[4][S.length()] = {0,};
if(S[0] == 'A') path[0][0] = 1;
else if(S[0] == 'C') path[1][0] = 1;
else if(S[0] == 'G') path[2][0] = 1;
else if(S[0] == 'T') path[3][0] = 1;
for(int i=1;i<S.length();i++) {
if(S[i] == 'A') {
path[0][i] = path[0][i-1]+1;
path[1][i] = path[1][i-1];
path[2][i] = path[2][i-1];
path[3][i] = path[3][i-1];
}
else if(S[i] == 'C') {
path[0][i] = path[0][i-1];
path[1][i] = path[1][i-1]+1;
path[2][i] = path[2][i-1];
path[3][i] = path[3][i-1];
}
else if(S[i] == 'G') {
path[0][i] = path[0][i-1];
path[1][i] = path[1][i-1];
path[2][i] = path[2][i-1]+1;
path[3][i] = path[3][i-1];
}
else if(S[i] == 'T') {
path[0][i] = path[0][i-1];
path[1][i] = path[1][i-1];
path[2][i] = path[2][i-1];
path[3][i] = path[3][i-1]+1;
}
}
for(int i=0;i<P.size();i++) {
for(int p=0;p<4;p++) {
int start = P[i] == 0 ? 0 : path[p][P[i]-1];
// cout << start << " " << path[p][Q[i]] << endl;
if(path[p][Q[i]] - start > 0) {
// cout << p << endl;
answer.push_back(p+1);
break;
}
}
}
return answer;
}
ずっと맞왜틀
(はい、なぜ間違っているのか)でしたが、接頭辞で解決する方法が思いつかず、参考にして解けました.まず私の話をする前に、答えを書いてください.例は、問題のCAGCTAを例に挙げます.
最初の文字を確認したら、まず最初の文字を記憶する
path
1を1に並べます.そして
path[1][0] = 1
が保存されます.そして一字一字確認して、数を数えました.
このようにした結果は以下の通りです.
path[0] = [0, 1, 1, 1, 1, 1, 2]
path[1] = [1, 1, 1, 2, 2, 2, 2]
path[2] = [0, 0, 1, 1, 1, 1, 1]
path[3] = [0, 0, 0, 0, 0, 1, 1]
これはどのように利用しますか.
path[0]を見ると、初めて1番indexに現れ、その後6番indexには現れません.
つまり、2-5の部分配列にはAはありません.
配列のインデックスがp,qの場合,path[0][q]−path[0][p]の値を調べることで個数を求めることができる.
問題の例として、まず
P[0] = 2 Q[0] = 4
を示す.2~4つ目は
GCC
で、Aは存在しないことがわかり、path[0][4]とpath[0][2]はいずれも1に等しい.したがって、0はAがないことを示す.//iはP、Qは配列index、jはpathは配列index
すなわち,上記の定式化後,
path[j][Q[i]] - path[j][P[i]]
と計算することができる.参考として、P[i]が0であれば
P[i]-1
I−1であるため、最初は삼항연산자
を用いて処理される.このようにpath[0]~path[3]を表示し、1つ以上あればその値を保存すればよい.小さい順(A->C->G->T)で確認し、1以上の値が出た場合、直ちに
break
を行うことができます.次はこの問題を解くときに生じるホットスポットです.
これは時間がかかりすぎたので...時間の複雑さは通過しなかったためかもしれないと考えられています.でも正しいと思う(?)何を言っているのか分かりませんが、他の人の言い方を参考にして、直接cppに変更して、結果は間違っています.
複数のケースでエラーがあることを確認するために、結果ページにエラーの
single
ケースが書かれていて、無言です.(真ん中のstartは上のコードと違い、3つの演算子ではないのは、そこに問題があったのでテストしました.)
上の写真を見ると,['T',[0],[0]のとき,
return value
3が現れる.4が表示されるはずなので、
cout
を使用してデバッグを試みます.結果は以下の通りです.
??? 突然現れた4...
cout
しか入っていませんが、なぜか4が出てきました.理解できなかったため、最終的に「法典」に質問メールを残し、以下のような回答を得た.
Hello,
We have forwarded this to our senior technical team to look into and they will be in touch after reviewing the details.
Kind regards,
Ajas
Codility Support
上級技術チームだけが問題を解決することができますが、突然思いついたのは、一部の企業が消費サービスを使用してコードテストを行っているのに、本当にこのような問題はありませんか?(解かなかったから落ちたのかもしれないけど)
解答と感想
遠い問題が難しくなるにつれて、問題も理解しにくくなりました...(英語が下手なせいか…)ㅠㅠㅠ他人の解答を見ても一度は読めないので、たくさんの解答を見ました...私はどのようにこれを
prefix
に解いたのか、やはり解決策があります...いずれにしても、最初は
prefix
で解決できなかったので、他の方法を試してみましたが、コディリティのミスで時間を無駄にしてしまったので、工夫を凝らした質問でしたㅠㅠ後でコディリティ側から回答があれば、内容を追加します.コメントサイト
Reference
この問題について(dility Lesson5 - GenomicRangeQuery), 我々は、より多くの情報をここで見つけました https://velog.io/@cookncoding/codility-Lesson5-GenomicRangeQueryテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol