#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
#include <tuple>
#include <random>
#include <chrono>
#include <cstdint>
typedef std::vector<std::size_t> DType;
static const std::size_t DisX = 16;
static const std::size_t DisY = 16;
typedef std::tuple<std::size_t,double,double,double, double, double, double> Line;//idx,x1,y1,x2,y2,a,b;
typedef std::vector<Line> LType;
typedef std::vector<std::set<std::size_t>> GType;
typedef std::pair<std::uint64_t, GType> RType;
DType MakeDataRev(std::size_t N){
DType vec(N);
std::size_t i = 0;
for (auto& o : vec)o = i++;
std::reverse(vec.begin(), vec.end());
return vec;
}
DType MakeDataRnd(std::size_t N){
DType vec(N);
std::size_t i = 0;
std::random_device rd;
std::mt19937 mt(rd());
for (auto& o : vec)o = i++;
std::shuffle(vec.begin(), vec.end(),mt);
return vec;
}
LType MakeLines(DType& vec){
LType R;
double X1 = 0;
double Y1 = 0;
double X2 = 0;
double Y2 = 0;
double A = 0;
double B = 0;
for (std::size_t i = 0; i < vec.size(); i++){
X1 = vec[i] * DisX;
Y1 = DisY;
X2 = i*DisX;
Y2 = 0;
A = 0;
if((X1-X2) != 0)A = (Y1 - Y2) / (X1 - X2);
B = Y1-(A*X1);
R.push_back(std::make_tuple(i,X1, Y1, X2, Y2, A, B));
}
return R;
}
bool IsCross(Line& A, Line& B){
double AA = (std::get<5>(A)-std::get<5>(B));
double BB = (std::get<6>(B)-std::get<6>(A));
double X =0;
if (AA != 0) X = BB / AA;
double Y = std::get<5>(A)*X + std::get<6>(A);
return (Y >= 0 && Y <= DisY)&&(X!=0);
//return X!=0;
}
RType MakeHoge(DType& vec){
GType R(vec.size());
auto ML = MakeLines(vec);
std::uint64_t count = 0;
for (size_t i = 0; i <ML.size() ; i++){
for (size_t j = i+1; j < ML.size(); j++)
{
//if (R[i].find(j) != R[i].end()) continue;
if (IsCross(ML[i], ML[j]) == true){
// R[std::get<0>(ML[i])].insert(std::get<0>(ML[j]));
// R[std::get<0>(ML[j])].insert(std::get<0>(ML[i]));
count++;
}
}
}
return std::make_pair(count,R);
}
RType TimeCount(std::size_t N, bool IsRandom = false){
DType D;
auto ST = std::chrono::high_resolution_clock::now();
if (IsRandom == false){
D = MakeDataRev(N);
}
else{
D = MakeDataRnd(N);
}
auto C = MakeHoge(D);
auto EN = std::chrono::high_resolution_clock::now();
auto El = std::chrono::duration_cast<std::chrono::milliseconds>(EN - ST);
std::cout << "Try "<<N<<" Line To Cross The " << C.first << " Count!!"<<std::endl;
std::cout << "Time Using At " << El.count() << "ms!!"<<std::endl;
return C;
}
int main(){
TimeCount(10240);
TimeCount(10240,true);
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8c2V0PgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8dHVwbGU+CiNpbmNsdWRlIDxyYW5kb20+CiNpbmNsdWRlIDxjaHJvbm8+CiNpbmNsdWRlIDxjc3RkaW50PgoKdHlwZWRlZiBzdGQ6OnZlY3RvcjxzdGQ6OnNpemVfdD4gRFR5cGU7CnN0YXRpYyBjb25zdCBzdGQ6OnNpemVfdCBEaXNYID0gMTY7CnN0YXRpYyBjb25zdCBzdGQ6OnNpemVfdCBEaXNZID0gMTY7Cgp0eXBlZGVmIHN0ZDo6dHVwbGU8c3RkOjpzaXplX3QsZG91YmxlLGRvdWJsZSxkb3VibGUsIGRvdWJsZSwgZG91YmxlLCBkb3VibGU+IExpbmU7Ly9pZHgseDEseTEseDIseTIsYSxiOwp0eXBlZGVmIHN0ZDo6dmVjdG9yPExpbmU+IExUeXBlOwoKdHlwZWRlZiBzdGQ6OnZlY3RvcjxzdGQ6OnNldDxzdGQ6OnNpemVfdD4+IEdUeXBlOwp0eXBlZGVmIHN0ZDo6cGFpcjxzdGQ6OnVpbnQ2NF90LCBHVHlwZT4gUlR5cGU7CgoKRFR5cGUgTWFrZURhdGFSZXYoc3RkOjpzaXplX3QgTil7CglEVHlwZSB2ZWMoTik7CglzdGQ6OnNpemVfdCBpID0gMDsKCglmb3IgKGF1dG8mIG8gOiB2ZWMpbyA9IGkrKzsKCglzdGQ6OnJldmVyc2UodmVjLmJlZ2luKCksIHZlYy5lbmQoKSk7CgoJcmV0dXJuIHZlYzsKfQpEVHlwZSBNYWtlRGF0YVJuZChzdGQ6OnNpemVfdCBOKXsKCURUeXBlIHZlYyhOKTsKCXN0ZDo6c2l6ZV90IGkgPSAwOwoKCXN0ZDo6cmFuZG9tX2RldmljZSByZDsKCXN0ZDo6bXQxOTkzNyBtdChyZCgpKTsKCgoJZm9yIChhdXRvJiBvIDogdmVjKW8gPSBpKys7CgoJc3RkOjpzaHVmZmxlKHZlYy5iZWdpbigpLCB2ZWMuZW5kKCksbXQpOwoKCXJldHVybiB2ZWM7Cn0KTFR5cGUgTWFrZUxpbmVzKERUeXBlJiB2ZWMpewoJTFR5cGUgUjsKCWRvdWJsZSBYMSA9IDA7Cglkb3VibGUgWTEgPSAwOwoJZG91YmxlIFgyID0gMDsKCWRvdWJsZSBZMiA9IDA7Cglkb3VibGUgQSA9IDA7Cglkb3VibGUgQiA9IDA7CgoJZm9yIChzdGQ6OnNpemVfdCBpID0gMDsgaSA8IHZlYy5zaXplKCk7IGkrKyl7CgkJWDEgPSB2ZWNbaV0gKiBEaXNYOwoJCVkxID0gRGlzWTsKCQlYMiA9IGkqRGlzWDsKCQlZMiA9IDA7CgkJQSA9IDA7CgkJaWYoKFgxLVgyKSAhPSAwKUEgPSAoWTEgLSBZMikgLyAoWDEgLSBYMik7CgoJCUIgPSBZMS0oQSpYMSk7CgkJUi5wdXNoX2JhY2soc3RkOjptYWtlX3R1cGxlKGksWDEsIFkxLCBYMiwgWTIsIEEsIEIpKTsKCX0KCglyZXR1cm4gUjsKfQoKYm9vbCBJc0Nyb3NzKExpbmUmIEEsIExpbmUmIEIpewoJZG91YmxlIEFBID0gKHN0ZDo6Z2V0PDU+KEEpLXN0ZDo6Z2V0PDU+KEIpKTsKCWRvdWJsZSBCQiA9IChzdGQ6OmdldDw2PihCKS1zdGQ6OmdldDw2PihBKSk7CgoJZG91YmxlIFggPTA7CglpZiAoQUEgIT0gMCkgWCA9IEJCIC8gQUE7Cglkb3VibGUgWSA9IHN0ZDo6Z2V0PDU+KEEpKlggKyBzdGQ6OmdldDw2PihBKTsKCglyZXR1cm4gKFkgPj0gMCAmJiBZIDw9IERpc1kpJiYoWCE9MCk7CgkvL3JldHVybiBYIT0wOwp9CgpSVHlwZSBNYWtlSG9nZShEVHlwZSYgdmVjKXsKCUdUeXBlIFIodmVjLnNpemUoKSk7CgoJYXV0byBNTCA9IE1ha2VMaW5lcyh2ZWMpOwoKCXN0ZDo6dWludDY0X3QgY291bnQgPSAwOwoKCWZvciAoc2l6ZV90IGkgPSAwOyBpIDxNTC5zaXplKCkgOyBpKyspewoJCWZvciAoc2l6ZV90IGogPSBpKzE7IGogPCBNTC5zaXplKCk7IGorKykKCQl7CgkJCS8vaWYgKFJbaV0uZmluZChqKSAhPSBSW2ldLmVuZCgpKSBjb250aW51ZTsKCQkJaWYgKElzQ3Jvc3MoTUxbaV0sIE1MW2pdKSA9PSB0cnVlKXsKCQkJLy8JUltzdGQ6OmdldDwwPihNTFtpXSldLmluc2VydChzdGQ6OmdldDwwPihNTFtqXSkpOwoJCQkvLwlSW3N0ZDo6Z2V0PDA+KE1MW2pdKV0uaW5zZXJ0KHN0ZDo6Z2V0PDA+KE1MW2ldKSk7CgkJCQljb3VudCsrOwoJCQl9CgoJCX0KCX0KCglyZXR1cm4gc3RkOjptYWtlX3BhaXIoY291bnQsUik7CgoKfQoKUlR5cGUgVGltZUNvdW50KHN0ZDo6c2l6ZV90IE4sIGJvb2wgSXNSYW5kb20gPSBmYWxzZSl7CglEVHlwZSBEOwoJYXV0byBTVCA9IHN0ZDo6Y2hyb25vOjpoaWdoX3Jlc29sdXRpb25fY2xvY2s6Om5vdygpOwoJCglpZiAoSXNSYW5kb20gPT0gZmFsc2UpewoJCUQgPSBNYWtlRGF0YVJldihOKTsKCX0KCWVsc2V7CgkJRCA9IE1ha2VEYXRhUm5kKE4pOwoJfQoKCWF1dG8gQyA9IE1ha2VIb2dlKEQpOwoJYXV0byBFTiA9IHN0ZDo6Y2hyb25vOjpoaWdoX3Jlc29sdXRpb25fY2xvY2s6Om5vdygpOwoJYXV0byBFbCA9IHN0ZDo6Y2hyb25vOjpkdXJhdGlvbl9jYXN0PHN0ZDo6Y2hyb25vOjptaWxsaXNlY29uZHM+KEVOIC0gU1QpOwoJc3RkOjpjb3V0IDw8ICJUcnkgIjw8Tjw8IiBMaW5lIFRvIENyb3NzIFRoZSAiIDw8IEMuZmlyc3QgPDwgIiBDb3VudCEhIjw8c3RkOjplbmRsOwoJc3RkOjpjb3V0IDw8ICJUaW1lIFVzaW5nIEF0ICIgPDwgRWwuY291bnQoKSA8PCAibXMhISI8PHN0ZDo6ZW5kbDsKCglyZXR1cm4gQzsKfQoKaW50IG1haW4oKXsKCQoJVGltZUNvdW50KDEwMjQwKTsKCVRpbWVDb3VudCgxMDI0MCx0cnVlKTsKCglyZXR1cm4gMDsKfQoKCgoKCg==