Interviews are considered puzzles.

This commit is contained in:
2015-02-14 12:45:32 +04:00
parent 12af9d1b7f
commit 0f638a71f4
10 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,60 @@
/* Check cf5-opt.vim defs.
VIM: let g:lcppflags="-std=c++11 -O2 -pthread"
VIM: let g:wcppflags="/O2 /EHsc /DWIN32"
VIM-: let g:cppflags=g:Iboost.g:Itbb
VIM-: let g:ldflags=g:Lboost.g:Ltbb.g:tbbmalloc.g:tbbmproxy
VIM-: let g:ldlibpath=g:Bboost.g:Btbb
VIM: let g:argv=""
*/
#include <iostream>
#include <vector>
#include <stdexcept>
int main ( void )
{try{
//
// Read length.
//
long long n;
std::cin >> n;
if ( n < 4 )
throw std::runtime_error( "Input length is not enough." );
//
// Read seq.
//
typedef std::vector<int> arr_type;
arr_type arr(n);
for ( int& i: arr )
std::cin >> i;
//
// Solve it.
//
long long s = 0;
for ( long long i: arr )
s += i;
long long d = arr[1]-arr[0];
if ( d != arr[2]-arr[1] && d != arr[3]-arr[2])
d = arr[2]-arr[1];
long long idx = (n+1)*n/2-(s-n*arr[0])/d;
//
//
//
long long missing = arr[0]+idx*d;
std::cout << missing;
return 0;
}
catch ( const std::exception& e )
{
std::cerr << std::endl
<< "std::exception(\"" << e.what() << "\")." << std::endl;
return 2;
}
catch ( ... )
{
std::cerr << std::endl
<< "unknown exception." << std::endl;
return 1;
}}

View File

@@ -0,0 +1,70 @@
/* Check cf5-opt.vim defs.
VIM: let g:lcppflags="-std=c++11 -O2 -pthread"
VIM: let g:wcppflags="/O2 /EHsc /DWIN32"
VIM-: let g:cppflags=g:Iboost.g:Itbb
VIM-: let g:ldflags=g:Lboost.g:Ltbb.g:tbbmalloc.g:tbbmproxy
VIM-: let g:ldlibpath=g:Bboost.g:Btbb
VIM: let g:argv=""
*/
#include <iostream>
#include <vector>
#include <stdexcept>
bool find_winner( unsigned n )
{
int z = 0; // amount of zeros
int m = 0; // amount of moves
while ( n )
{
unsigned b = n & 0x1; // get the last bit.
if ( b )
m += z;
else
z++;
n >>= 1;
}
return m % 2;
}
int main ( void )
{try{
//
// Read length.
//
long long n;
std::cin >> n;
//
// Read seq.
//
typedef std::vector<unsigned> arr_type;
arr_type arr(n);
for ( unsigned& i: arr )
std::cin >> i;
//
// Solve it.
//
for ( unsigned i: arr )
{
if ( find_winner( i ) )
std::cout << "First Player" << std::endl;
else
std::cout << "Second Player" << std::endl;
}
return 0;
}
catch ( const std::exception& e )
{
std::cerr << std::endl
<< "std::exception(\"" << e.what() << "\")." << std::endl;
return 2;
}
catch ( ... )
{
std::cerr << std::endl
<< "unknown exception." << std::endl;
return 1;
}}

View File

@@ -0,0 +1,239 @@
/* Check cf5-opt.vim defs.
VIM: let g:lcppflags="-std=c++11 -O2 -pthread"
VIM: let g:wcppflags="/O2 /EHsc /DWIN32"
VIM: let g:argv=""
*/
#include <iostream>
#include <exception>
#include <vector>
#include <algorithm>
#include <string>
int testinput[] = {
1,0,0,0,1,0,0,0,0
};
// find bug.
int solution3(std::vector<int>& A) {
int n = A.size();
int i = n - 1;
int result = -1;
int k = 0;
int maximal = 0;
while (i > 0)
{
if (A[i] == 1)
{
k = k + 1;
if (k >= maximal)
{
maximal = k;
result = i;
}
}
else
{
k = 0;
}
i = i - 1;
}
if (A[i] == 1 && k + 1 > maximal) // <- bug is here. there should be k+1 >= maximal
result = 0;
return result;
}
const char * a1 = "abc";
const char * a2 = "Abc";
int solution4(const std::string & s1, const std::string & s2)
{
std::string::const_iterator s1it = s1.begin();
std::string::const_iterator s1et = s1.end();
std::string::const_iterator s2it = s2.begin();
std::string::const_iterator s2et = s2.end();
for ( ; s1it!=s1et && s2it!=s2et; ++s1it, ++s2it )
{
char c1 = toupper(*s1it);
char c2 = toupper(*s2it);
if ( c1 < c2 )
return -1;
else if ( c2 < c1 )
return 1;
}
if ( s1it==s1et && s2it==s2et )
return 0;
else if ( s1it==s1et )
return -1;
else
return 1;
}
int solution2(int blx1, int bly1, int trx1, int try1, int blx2, int bly2, int trx2, int try2)
{
if ( blx1 > trx1 )
std::swap( blx1, trx1 );
if ( bly1 > try1 )
std::swap( bly1, try1 );
if ( blx2 > trx2 )
std::swap( blx2, trx2 );
if ( bly2 > try2 )
std::swap( bly2, try2 );
if ( trx1 < blx2
|| trx2 < blx1
|| try1 < bly2
|| try2 < bly1 )
return 0;
long long x[4] = { blx1,trx1,blx2,trx2 };
std::sort( &x[0], &x[4]);
long long y[4] = { bly1,try1,bly2,try2 };
std::sort( &y[0], &y[4]);
unsigned long long a = (unsigned long long)(x[2]-x[1])*(unsigned long long)(y[2]-y[1]);
return ( a <= 2147483647 ) ? (int)a : -1;
}
int solution1( std::vector<int> & a )
{
typedef std::vector<int> v_t;
std::sort(a.begin(),a.end());
long long s = 0;
v_t::const_iterator it=a.begin();
v_t::const_iterator et=a.end();
v_t::const_iterator jt;
for ( jt = it; it != et && *it == *jt; ++it );
long long ic = it - jt;
s += ic*(ic-1)/2;
for ( ; it != et; )
{
for ( jt = it; it != et && *it == *jt; ++it );
long long pc = ic;
ic = it - jt;
s += ic*(ic-1)/2;
s += ic*pc;
}
const long long lim = 100000000;
return ( s <= lim ) ? s : -1;
}
// you can also use includes, for example:
int solution_demo1( std::vector<int> & a )
{
if ( !a.size() )
return -1;
typedef std::vector<int>::const_iterator iterator;
typedef std::vector<long long> ub_t;
int s = 0;
ub_t ub;
for ( iterator it=a.begin(), ib=a.begin(), ie=a.end();
it!=ie; ++it )
{
int c = it-ib;
long long l = c-*it;
long long r = c+*it;
ub_t::iterator jt = std::lower_bound( ub.begin(), ub.end(), l);
s += ub.end()-jt;
if ( s > 10000000 )
return -1;
jt = std::upper_bound( ub.begin(), ub.end(), r);
ub.insert(jt, r);
}
return s;
}
// you can also use includes, for example:
int solution_demo2( const std::vector<int> & a )
{
typedef std::vector<int>::const_iterator iterator;
//
// There is no solution if array 'a' has no elements. However,
// per task condition 'a' is non-empty. So, I don't consider that
// case.
//
std::vector<bool> m( a.size(), false );
//
// This is the index.
//
int cvrp = 0;
//
// Iterate over array and find the index that inserts
// element into m. That will be wanted index.
//
for ( iterator it=a.begin(), ib=a.begin(), ie=a.end();
it!=ie; ++it )
{
if ( !m[*it] )
{
m[*it]=true;
cvrp = it - ib;
}
}
//
// Make it index.
//
return cvrp;
}
int main ( void )
{try{
// std::cout << solution( 0,0,2,2, 1,1,3,3 ) << std::endl;
// std::cout << solution( -2147483648,-2147483648,2147483647,2147483647, -2147483640,-2147483640,2147483640,2147483640 ) << std::endl;
// std::cout << solution( std::string(a1), std::string(a2) ) << std::endl;
#if 1
int cnt = sizeof(testinput)/sizeof(testinput[0]);
std::vector<int> a;
//std::cout << solution( a ) << std::endl;
a.reserve(cnt);
for ( int i = 0; i < cnt; ++i )
a.push_back(testinput[i]);
std::cout << solution3( a ) << std::endl;
/*
{
std::vector<int> b(100000,1);
std::cout << solution( b ) << std::endl;
}
{
std::vector<int> b(10000,1);
std::cout << solution( b ) << std::endl;
}
{
std::vector<int> b(1000,1);
std::cout << solution( b ) << std::endl;
}
*/
#endif
return 0;
}
catch ( const std::exception& e )
{
std::cerr << std::endl
<< "std::exception(\"" << e.what() << "\")." << std::endl;
return 2;
}
catch ( ... )
{
std::cerr << std::endl
<< "unknown exception." << std::endl;
return 1;
}}

View File

@@ -0,0 +1,140 @@
/*
VIM: let g:lcppflags="-std=c++11 -O2 -pthread"
VIM: let g:wcppflags="/O2 /EHsc /DWIN32"
VIM: let g:argv=""
*/
#include <iostream>
#include <stdexcept>
#include <vector>
#include <algorithm>
#include <string>
#include <fstream>
/*
#1 print numbers from 1 to N and if i is 3 mutltiple print "Fizz", if 5 multiple "Buzz".
If both then "FizzBuzz". Otherwise print number.
int N;
std::cin >> N;
for (int i = 1; i <= N; i++)
{
if (!(i % 3))
std::cout << "Fizz";
if (!(i % 5))
std::cout << "Buzz";
if ((i % 3) && (i % 5))
std::cout << i;
std::cout << std::endl;
}
*/
/*
#2 print complement of N.
unsigned int c = 1;
unsigned int b = N;
while (b)
{
b >>= 1;
c <<= 1;
}
return c-1-N;
alternative:
if ( !N )
return 0;
unsigned int b = N;
while ((b&(b-1)))
auto n = b&(b-1);
return (b<<1)-1-N;
*/
/*
#3
char a[] = "";
sizeof(a)?
*/
/*
#4
struct A {
int x;
A(int a) : x(a) {}
A( const A& a ) { x=a.x; x++; }
opertaor = ... { x=a.x; x--; }
};
A a(4);
A b = a;
std::cout << b.x;
3?
4?
5?
*/
/*
#5
struct A {
int u;
int l;
A(int i) : l(i), u(l + 1) {}
};
A a(5);
print a.l a.u
5 6
compilation fail
5 garbage ?
*/
//#6
/*
struct A {
int d;
virtual ~A(){}
};
sizeof(A)? 8 || 16
*/
//#7
/*
conceptual support for function call
system stack
data segment
processor's register
text segment
heap
*/
int main ( void )
{try{
A a(5);
std::cout << a.l << ' ' << a.u ;
char c;
std::cin >> c;
return 0;
}
catch ( const std::exception& e )
{
std::cerr << std::endl
<< "std::exception(\"" << e.what() << "\")." << std::endl;
return 2;
}
catch ( ... )
{
std::cerr << std::endl
<< "unknown exception." << std::endl;
return 1;
}}

View File

@@ -0,0 +1,493 @@
/* Check .vimrc.local defs.
VIM: let g:lcppflags="-std=c++11 -O2 -pthread"
VIM: let g:wcppflags="/O2 /EHsc /DWIN32"
VIM: let g:argv=""
*/
#include <assert.h>
#include <map>
#include <limits>
#include <iostream>
#include <sstream>
// interval_map<K,V> is a data structure that efficiently associates intervals of keys of type K with values of type V.
// Your task is to implement the assign member function of this data structure, which is outlined below.
// interval_map<K, V> is implemented on top of std::map. In case you are not entirely sure which functions std::map provides,
// what they do and which guarantees they provide, we have attached an excerpt of the C++1x draft standard at the end of this
// file for your convenience.
// Each key-value-pair (k,v) in the m_map member means that the value v is associated to the interval from k (including) to
// the next key (excluding) in m_map.
// Example: the std::map (0,'A'), (3,'B'), (5,'A') represents the mapping
// 0 -> 'A'
// 1 -> 'A'
// 2 -> 'A'
// 3 -> 'B'
// 4 -> 'B'
// 5 -> 'A'
// 6 -> 'A'
// 7 -> 'A'
// ... all the way to numeric_limits<key>::max()
// The representation in m_map must be canonical, that is, consecutive map entries must not have the same value:
// ..., (0,'A'), (3,'A'), ... is not allowed.
// Initially, the whole range of K is associated with a given initial value, passed to the constructor.
template<class K, class V>
class interval_map {
friend void IntervalMapTest();
private:
std::map<K,V> m_map;
public:
// constructor associates whole range of K with val by inserting (K_min, val) into the map
interval_map( V const& val) {
m_map.insert(m_map.begin(),std::make_pair(std::numeric_limits<K>::min(),val));
};
// Assign value val to interval [keyBegin, keyEnd).
// Overwrite previous values in this interval. Do not change values outside this interval.
// Conforming to the C++ Standard Library conventions, the interval includes keyBegin, but excludes keyEnd.
// If !( keyBegin < keyEnd ), this designates an empty interval, and assign must do nothing.
void assign( K const& keyBegin, K const& keyEnd, const V& val ) {
//
// If !( keyBegin < keyEnd ), this designates an empty interval, and
// assign must do nothing.
//
if ( !(keyBegin < keyEnd ) )
return;
//
// - is bounded below, with the lowest value being std::numeric_limits<K>::min();
// std::numeric_limits<duble>::min() actually is not the smalles number.
//
if (keyBegin < std::numeric_limits<K>::min())
throw std::runtime_error("K should be bounded below, with the lowest value being std::numeric_limits<K>::min().");
//
// Find the interval pointer before which the new interval ends.
//
auto ie = m_map.lower_bound(keyEnd);
//
// If there is a need to break the last interval with keyEnd do it now.
// Everything prior 'ie' till 'ib' will be removed later.
//
if ( ie == m_map.end() && keyEnd < std::numeric_limits<K>::max()
|| ie != m_map.end() && keyEnd < ie->first ) {
if (!( std::prev(ie)->second == val ))
ie = m_map.insert(ie, std::make_pair(keyEnd,std::prev(ie)->second));
}
//
// If the interval next to the inserting one should be joined?
//
else if (ie != m_map.end() && ie->second == val)
++ie;
//
// Find the interval pointer before which the new interval begins.
//
auto ib = m_map.lower_bound( keyBegin );
//
// If the interval before should be joined then ...
// Note: there should always be std::numeric_limits<K>::min()
//
if (ib != m_map.begin() && std::prev(ib)->second == val)
--ib;
//
// If keyBegin is less than 'ib' then insert an new interval.
//
else if ( ib == m_map.end() || keyBegin < ib->first )
ib = m_map.insert(ib, std::make_pair(keyBegin, val));
//
// Otherwise just change the value since keyBegin matches with an
// existing interval.
//
else
ib->second = val;
//
// Removed the range between ib and ie.
//
m_map.erase( ++ib, ie );
}
// look-up of the value associated with key
V const& operator[]( K const& key ) const {
return ( --m_map.upper_bound(key) )->second;
}
private:
//
// Since this is a template class, I assume this method will be
// instantiated only in IntervalMapTest. Hence, key and value are pretty
// printable.
//
std::ostream& print( std::ostream& os ) const {
for( auto e: m_map )
os << '[' << e.first << ',' << e.second << ']';
return os;
}
};
// Key type K
// - besides being copyable and assignable, is less-than comparable via operator< ;
// - is bounded below, with the lowest value being std::numeric_limits<K>::min();
// - does not implement any other operations, in particular no equality comparison or arithmetic operators.
template<typename T>
class test_key {
T value;
public:
/*explicit*/ test_key( T v )
: value(v)
{}
bool operator < ( const test_key& op ) const {
return value < op.value;
}
std::ostream& print( std::ostream& os ) const {
return os << value;
}
};
namespace std {
//
// I hope this much of implementation of numeric_limits is enough for my
// tests.
//
template <typename T>
struct numeric_limits<::test_key<T> > : public numeric_limits<T> {
typedef ::test_key<T> value_type;
typedef numeric_limits<T> base_type;
static value_type min() {
return value_type( base_type::min() );
}
static value_type max() {
return value_type( base_type::max() );
}
};
}
template <typename T>
inline std::ostream& operator << ( std::ostream& os, test_key<T> t ) {
return t.print(os);
}
template <typename T>
void test_test_key() {
typedef test_key<T> test_type;
test_type a(T(3.5));
test_type b(T(5.5));
std::cout << "a<b before a=b: " << (a < b) << std::endl;
a = b;
std::cout << "a<b after a=b: " << (a < b) << std::endl;
std::cout << "min: " << std::numeric_limits<test_type>::min() << std::endl;
std::cout << "max: " << std::numeric_limits<test_type>::max() << std::endl;
}
// Value type V
// - besides being copyable and assignable, is equality-comparable via operator== ;
// - does not implement any other operations.
template<typename T>
class test_value {
T value;
public:
/*explicit*/ test_value( T v )
: value(v)
{}
bool operator == ( const test_value& op ) const {
return value == op.value;
}
std::ostream& print( std::ostream& os ) const {
return os << value;
}
};
template <typename T>
void test_test_value() {
test_value<T> a(T(3.5));
test_value<T> b(T(5.5));
std::cout << "a==b before a=b: " << (a == b) << std::endl;
a = b;
std::cout << "a==b after a=b: " << (a == b) << std::endl;
}
template <typename T>
inline std::ostream& operator << ( std::ostream& os, test_value<T> t ) {
return t.print(os);
}
//
// Test throws this exception if fails.
//
struct test_failed : public std::logic_error {
test_failed()
: logic_error("Test failed.")
{}
};
//
// The representation in m_map must be canonical, that is, consecutive map entries must not have the same value:
// ..., (0,'A'), (3,'A'), ... is not allowed.
//
template <class C>
void test_if_canonical(const C& c) {
for (auto it = std::next(c.begin()); it != c.end(); ++it) {
if (it->second == std::prev(it)->second)
throw test_failed();
}
}
// Provide a function IntervalMapTest() here that tests the functionality of the interval_map,
// for example using a map of unsigned int intervals to char.
// Many solutions we receive are incorrect. Consider using a randomized test to discover
// the cases that your implementation does not handle correctly.
void IntervalMapTest() {
try {
#if 0
std::cout << "=============================================" << std::endl;
std::cout << "Test test_key<int>" << std::endl;
test_test_key<int>();
std::cout << "=============================================" << std::endl;
std::cout << "Test test_key<double>" << std::endl;
test_test_key<double>();
std::cout << "=============================================" << std::endl;
std::cout << "Test test_value<int>" << std::endl;
test_test_value<int>();
std::cout << "=============================================" << std::endl;
std::cout << "Test test_value<double>" << std::endl;
test_test_value<double>();
#endif
// Check that key value is not less the std::numeric_limits<key>::min().
try {
interval_map<test_key<double>, test_value<double>> im(0);
im.assign(0, 500, 3);
throw test_failed();
}
catch (const std::runtime_error&) {
}
//
// Check map for some interesting values.
//
typedef test_key<int> key;
typedef test_value<int> val;
interval_map<key, val> im(0);
std::stringstream log;
auto TEST = [&log,&im](const std::string& golden ) {
test_if_canonical(im.m_map);
std::stringstream ss;
im.print(ss);
log << ss.str() << std::endl;
if (ss.str() != golden)
throw test_failed();
};
// check initial state.
TEST("[-2147483648,0]");
im.assign(std::numeric_limits<key>::min(), std::numeric_limits<key>::min(), -1);
TEST("[-2147483648,0]");
im.assign(std::numeric_limits<key>::max(), std::numeric_limits<key>::max(), -1);
TEST("[-2147483648,0]");
im.assign(0, 0, -1);
TEST("[-2147483648,0]");
im.assign(std::numeric_limits<key>::min(), std::numeric_limits<key>::max(), -1);
TEST("[-2147483648,-1]");
im.assign(1000, 2000, 1);
TEST("[-2147483648,-1][1000,1][2000,-1]");
im.assign(500, 1500, 1);
TEST("[-2147483648,-1][500,1][2000,-1]");
im.assign(1000, 1500, 2);
TEST("[-2147483648,-1][500,1][1000,2][1500,1][2000,-1]");
im.assign(0, 500, 3);
TEST("[-2147483648,-1][0,3][500,1][1000,2][1500,1][2000,-1]");
im.assign(-1000, -500, 3);
TEST("[-2147483648,-1][-1000,3][-500,-1][0,3][500,1][1000,2][1500,1][2000,-1]");
im.assign(-500, 0, 3);
TEST("[-2147483648,-1][-1000,3][500,1][1000,2][1500,1][2000,-1]");
im.assign(-500, 0, 4);
TEST("[-2147483648,-1][-1000,3][-500,4][0,3][500,1][1000,2][1500,1][2000,-1]");
im.assign(2000, std::numeric_limits<key>::max(), 4);
TEST("[-2147483648,-1][-1000,3][-500,4][0,3][500,1][1000,2][1500,1][2000,4]");
im.assign(3000, std::numeric_limits<key>::max(), 5);
TEST("[-2147483648,-1][-1000,3][-500,4][0,3][500,1][1000,2][1500,1][2000,4][3000,5]");
im.assign(2000, 3000, 5);
TEST("[-2147483648,-1][-1000,3][-500,4][0,3][500,1][1000,2][1500,1][2000,5]");
im.assign(std::numeric_limits<key>::min(), -1000, 4);
TEST("[-2147483648,4][-1000,3][-500,4][0,3][500,1][1000,2][1500,1][2000,5]");
im.assign(std::numeric_limits<key>::min(), -2000, 5);
TEST("[-2147483648,5][-2000,4][-1000,3][-500,4][0,3][500,1][1000,2][1500,1][2000,5]");
im.assign(-2000, -1000, 5);
TEST("[-2147483648,5][-1000,3][-500,4][0,3][500,1][1000,2][1500,1][2000,5]");
im.assign(-750, 1750, 4);
TEST("[-2147483648,5][-1000,3][-750,4][1750,1][2000,5]");
im.assign(-1000, 2000, 5);
TEST("[-2147483648,5]");
std::cout << log.str() << std::endl;
std::cout << "PASS" << std::endl;
}
catch (const test_failed&) {
std::cerr << "FAIL: test_failed" << std::endl;
}
catch (const std::exception& e)
{
std::cerr << std::endl
<< "FAIL: std::exception(\"" << e.what() << "\")" << std::endl;
}
catch (...)
{
std::cerr << std::endl
<< "FAIL: unknown exception." << std::endl;
}}
int main(int argc, char* argv[]) {
IntervalMapTest();
return 0;
}
/*
The following paragraphs from the final draft of the C++1x ISO standard describe the available
operations on a std::map container, their effects and their complexity.
23.2.1 General container requirements
<EFBFBD>1 Containers are objects that store other objects. They control allocation and deallocation of
these objects through constructors, destructors, insert and erase operations.
<EFBFBD>6 begin() returns an iterator referring to the first element in the container. end() returns
an iterator which is the past-the-end value for the container. If the container is empty,
then begin() == end();
24.2.1 General Iterator Requirements
<EFBFBD>1 Iterators are a generalization of pointers that allow a C++ program to work with different
data structures.
<EFBFBD>2 Since iterators are an abstraction of pointers, their semantics is a generalization of most
of the semantics of pointers in C++. This ensures that every function template that takes
iterators works as well with regular pointers.
<EFBFBD>5 Just as a regular pointer to an array guarantees that there is a pointer value pointing past
the last element of the array, so for any iterator type there is an iterator value that points
past the last element of a corresponding sequence. These values are called past-the-end values.
Values of an iterator i for which the expression *i is defined are called dereferenceable.
The library never assumes that past-the-end values are dereferenceable. Iterators can also have
singular values that are not associated with any sequence. [ Example: After the declaration of
an uninitialized pointer x (as with int* x;), x must always be assumed to have a singular
value of a pointer. <20>end example ] Results of most expressions are undefined for singular
values; the only exceptions are destroying an iterator that holds a singular value, the
assignment of a non-singular value to an iterator that holds a singular value, and, for
iterators that satisfy the DefaultConstructible requirements, using a value-initialized
iterator as the source of a copy or move operation.
<EFBFBD>10 An invalid iterator is an iterator that may be singular. (This definition applies to pointers,
since pointers are iterators. The effect of dereferencing an iterator that has been invalidated
is undefined.)
23.2.4 Associative containers
<EFBFBD>1 Associative containers provide fast retrieval of data based on keys. The library provides four
basic kinds of associative containers: set, multiset, map and multimap.
<EFBFBD>4 An associative container supports unique keys if it may contain at most one element for each key.
Otherwise, it supports equivalent keys. The set and map classes support unique keys; the multiset
and multimap classes support equivalent keys.
<EFBFBD>5 For map and multimap the value type is equal to std::pair<const Key, T>. Keys in an associative
container are immutable.
<EFBFBD>6 iterator of an associative container is of the bidirectional iterator category.
(i.e., an iterator i can be incremented and decremented: ++i; --i;)
<EFBFBD>9 The insert member functions (see below) shall not affect the validity of iterators and references
to the container, and the erase members shall invalidate only iterators and references to the erased
elements.
<EFBFBD>10 The fundamental property of iterators of associative containers is that they iterate through the
containers in the non-descending order of keys where non-descending is defined by the comparison
that was used to construct them.
Associative container requirements (in addition to general container requirements):
std::pair<iterator, bool> insert(std::pair<const key_type, T> const& t)
Effects: Inserts t if and only if there is no element in the container with key equivalent to the key of t.
The bool component of the returned pair is true if and only if the insertion takes place, and the iterator
component of the pair points to the element with key equivalent to the key of t.
Complexity: logarithmic
iterator insert(const_iterator p, std::pair<const key_type, T> const& t)
Effects: Inserts t if and only if there is no element with key equivalent to the key of t in containers with
unique keys. Always returns the iterator pointing to the element with key equivalent to the key of t.
Complexity: logarithmic in general, but amortized constant if t is inserted right before p.
size_type erase(key_type const& k)
Effects: Erases all elements in the container with key equivalent to k. Returns the number of erased elements.
Complexity: log(size of container) + number of elements with key k
iterator erase(const_iterator q)
Effects: Erases the element pointed to by q. Returns an iterator pointing to the element immediately following
q prior to the element being erased. If no such element exists, returns end().
Complexity: Amortized constant
iterator erase(const_iterator q1, const_iterator q2)
Effects: Erases all the elements in the left-inclusive and right-exclusive range [q1,q2). Returns q2.
Complexity: Amortized O(N) where N has the value distance(q1, q2).
void clear()
Effects: erase(begin(), end())
Post-Condition: empty() returns true
Complexity: linear in size().
iterator find(key_type const& k);
Effects: Returns an iterator pointing to an element with the key equivalent to k, or end() if such an element is not found
Complexity: logarithmic
size_type count(key_type const& k)
Effects: Returns the number of elements with key equivalent to k
Complexity: log(size of map) + number of elements with key equivalent to k
iterator lower_bound(key_type const& k)
Effects: Returns an iterator pointing to the first element with key not less than k, or end() if such an element is not found.
Complexity: logarithmic
iterator upper_bound(key_type const& k)
Effects: Returns an iterator pointing to the first element with key greater than k, or end() if such an element is not found.
Complexity: logarithmic
23.4.1 Class template map
<EFBFBD>1 A map is an associative container that supports unique keys (contains at most one of each key value) and provides
for fast retrieval of values of another type T based on the keys. The map class supports bidirectional iterators.
23.4.1.2 map element access
T& operator[](const key_type& x);
Effects: If there is no key equivalent to x in the map, inserts value_type(x, T()) into the map.
Returns: A reference to the mapped_type corresponding to x in *this.
Complexity: logarithmic.
T& at(const key_type& x);
const T& at(const key_type& x) const;
Returns: A reference to the element whose key is equivalent to x.
Throws: An exception object of type out_of_range if no such element is present.
Complexity: logarithmic.
*/

View File

@@ -0,0 +1,47 @@
//aschoedl@think-cell.com
#include <iostream>
#include <vector>
template<typename T, typename IT>
int binary_search( IT ib, IT ie, const T& e )
{
if ( ib == ie || e < *ib || *(ie-1) < e )
return -1;
auto base = ib;
auto im = (ib+(ie-ib)/2);
while ( ib != im )
{
if ( e < *im )
ie = im;
else
ib = im;
im = (ib+(ie-ib)/2);
}
return !(*ib < e) ? (ib - base) : -1;
}
void main ( void )
{
std::vector<int> v = { 0,1,2,3,4,4,4,4,5,6,7,8,9,11};
for ( int i = 0; i < v.size(); i++ ) {
int j = binary_search( v.begin(), v.end(), v[i] );
std::cout << v[i] << "->" << j << std::endl;
}
std::cout << binary_search( v.begin(), v.end(), 10 ) << std::endl;
std::cout << binary_search( v.begin(), v.end(), 12 ) << std::endl;
std::cout << binary_search( v.begin(), v.end(), -4 ) << std::endl;
std::vector<int> v0;
std::cout << binary_search( v0.begin(), v0.end(), 10 ) << std::endl;
std::vector<int> v1 = { 1 };
std::cout << binary_search( v1.begin(), v1.end(), -10 ) << std::endl;
std::cout << binary_search( v1.begin(), v1.end(), 10 ) << std::endl;
std::cout << binary_search( v1.begin(), v1.end(), 1 ) << std::endl;
}

View File

@@ -0,0 +1,52 @@
/*
VIM: let g:lcppflags="-std=c++11 -O2 -pthread"
VIM: let g:wcppflags="/O2 /EHsc /DWIN32"
VIM: let g:argv=""
*/
#include <iostream>
#include <stdexcept>
#include <vector>
#include <algorithm>
#include <string>
int solution( std::vector<int> & a )
{
long long s = 0;
for ( auto it = a.begin(), ie=a.end(); it != ie; ++it ) {
s += *it;
}
long long t = 0;
for ( auto it = a.begin(), ie=a.end(); it != ie; ++it ) {
if ( (s-*it)%2 == 0 && t == (s-*it)/2 )
return it - a.begin();
t += *it;
}
return -1;
}
int main ( void )
{try{
#if 1
std::vector<int> a = {
-1,3,-4,5,1,-6,2,1
};
std::cout << solution( a ) << std::endl;
#endif
return 0;
}
catch ( const std::exception& e )
{
std::cerr << std::endl
<< "std::exception(\"" << e.what() << "\")." << std::endl;
return 2;
}
catch ( ... )
{
std::cerr << std::endl
<< "unknown exception." << std::endl;
return 1;
}}

View File

@@ -0,0 +1,51 @@
/*
VIM: let g:lcppflags="-std=c++11 -O2 -pthread"
VIM: let g:wcppflags="/O2 /EHsc /DWIN32"
VIM: let g:argv=""
*/
#include <iostream>
#include <stdexcept>
#include <vector>
#include <algorithm>
#include <string>
int solution( std::vector<int> & a )
{
auto n = a.size();
int i = 0;
for (int c = 0; c < n; ++c ) {
auto new_i = i + a[i];
if (new_i < 0 || n <= new_i)
return i;
i = new_i;
}
return -1;
}
int main ( void )
{try{
#if 1
std::vector<int> a = {
2,3,-1,1,-1
};
std::cout << solution( a ) << std::endl;
#endif
return 0;
}
catch ( const std::exception& e )
{
std::cerr << std::endl
<< "std::exception(\"" << e.what() << "\")." << std::endl;
return 2;
}
catch ( ... )
{
std::cerr << std::endl
<< "unknown exception." << std::endl;
return 1;
}}

View File

@@ -0,0 +1,57 @@
/*
VIM: let g:lcppflags="-std=c++11 -O2 -pthread"
VIM: let g:wcppflags="/O2 /EHsc /DWIN32"
VIM: let g:argv=""
*/
#include <iostream>
#include <stdexcept>
#include <vector>
#include <algorithm>
#include <string>
int solution( std::vector<int> & a )
{
int max_e = 10001; //
std::vector<int> c(max_e, 0);
for ( auto e : a ) {
++c[e];
}
int m = 0;
int mi = 0;
for ( auto it = c.begin(); it != c.end(); ++it ) {
if (*it > m)
{
m = *it;
mi = it - c.begin();
}
}
return mi;
}
int main ( void )
{try{
#if 1
std::vector<int> a = {
0, 0, 1, 2, 0, 10000, 10000, 10000
};
std::cout << solution( a ) << std::endl;
#endif
return 0;
}
catch ( const std::exception& e )
{
std::cerr << std::endl
<< "std::exception(\"" << e.what() << "\")." << std::endl;
return 2;
}
catch ( ... )
{
std::cerr << std::endl
<< "unknown exception." << std::endl;
return 1;
}}

View File

@@ -0,0 +1,88 @@
/*
VIM: let g:lcppflags="-std=c++11 -O2 -pthread"
VIM: let g:wcppflags="/O2 /EHsc /DWIN32"
VIM: let g:argv=""
*/
#include <iostream>
#include <stdexcept>
#include <vector>
#include <algorithm>
#include <string>
/*
int solution(vector<int>& A) {
int n = A.size();
int i = n - 1;
int result = -1;
int k = 0;
int maximal = 0;
while (i > 0) {
if (A[i] == 1) {
k = k + 1;
if (k >= maximal) {
maximal = k;
result = i;
}
}
else {
k = 0;
}
i = i - 1;
}
if (A[i] == 1 && k + 1 > maximal)
result = 0;
return result;
}
*/
using namespace std;
int solution(vector<int>& A) {
int n = A.size();
int i = n - 1;
int result = -1;
int k = 0;
int maximal = 0;
while (i > 0) {
if (A[i] == 1) {
k = k + 1;
if (k >= maximal) {
maximal = k;
result = i;
}
}
else {
k = 0;
}
i = i - 1;
}
if (A[i] == 1 && k + 1 >= maximal)
result = 0;
return result;
}
int main ( void )
{try{
#if 1
std::vector<int> a = {
1,1,1,0,1,1,1,0,1
};
std::cout << solution( a ) << std::endl;
#endif
return 0;
}
catch ( const std::exception& e )
{
std::cerr << std::endl
<< "std::exception(\"" << e.what() << "\")." << std::endl;
return 2;
}
catch ( ... )
{
std::cerr << std::endl
<< "unknown exception." << std::endl;
return 1;
}}