| QUOTE | ||||||
| You are working in the city administration and your job is it to count the number of citizens which live in a street. You have to note down when people move into the street and move out and be able to answer how many people live in a part of the street. All houses are on one side of the street and are number from 1 to N. When nobody lives in a house then there is no house, meaning either it's still a empty site where you can build a house or it has been destroyed when the last people moved out. When you get the job the street is just finished and nobody lives in that street. You need to be able to answer the question how many people live from the Ath house to the Bth house where both A and B are bigger or equal than 1 and smaller or equal than N. Both the Ath house and the Bth house must be counted. If A is equal to B then you need to say how many people live in that specific house. For example consider you have a street where the following people live
You may be asked how many people live from house 2 to house 4 which would be 2 + 5 + 6 meaning 13 or from house 1 to house 1 which would be 3. People can move in and out at any time. The program should read the instructions from an input file (in.txt) and write to an output file (out.txt) the answers. The input will be under the forms of commands which are passed a few parameters. Each command comes on a new line. The commands are:
An example of an input file would be
and the corresponding output file would be
Both the input and output file might contain trailing new lines at the end of the file or spaces at the beginning or end of a line or several spaces to seperate the arguments. All input data is valid and doesn't need to be checked. The program must be deterministic, meaning running it twice must produce the same output. |
| CODE |
| #include<fstream> #include<vector> using namespace std; int main() { ifstream in("in.txt"); ofstream out("out.txt"); vector<int>street; char c; while(in>>c) { switch(c) { case 'J': { size_t size; in>>size; street.resize(size, 0); } break; case 'R': return 0; case 'M': { size_t index; int people; in>>index>>people; street[index-1] += people; } break; case 'C': { size_t begin,last; in>>begin>>last; --begin; --last; if(last < begin) swap(last, begin); int people = 0; for(;begin <= last; ++begin) people += street[begin]; out<<people<<endl; } break; } } } |
| CODE |
| #include<fstream> #include<vector> using namespace std; int main() { ifstream in("in.txt"); ofstream out("out.txt"); vector<int>street; char c; while(in>>c) { switch(c) { case 'J': { size_t size; in>>size; street.resize(size, 0); } break; case 'R': return 0; case 'M': { size_t index; int people; in>>index>>people; --index; size_t size = street.size(); for(;index < size; ++index){ street[index] += people; } } break; case 'C': { size_t start,last; in>>start>>last; --start; --last; if(last < start) swap(last, start); if(start == 0) out<<street[last]<<endl; else out<<street[last]-street[start-1]<<endl; } break; } } } |
| CODE |
| house: 1 2 3 4 people: 3 2 5 6 |
| CODE |
| #include<vector> #include<fstream> #include<cassert> using namespace std; size_t align_tree_size(size_t number) { size_t num = 1; while(num < number) num *= 2; return num; } size_t tree_size(size_t base) { size_t size = base; base = align_tree_size(base); while(base != 0) { base /= 2; size += base; } return size; } inline size_t move_upward(size_t index) { return ((index+1)/2)-1; } inline size_t move_left_downward(size_t index) { return (index+1)*2 - 1; } inline size_t move_right_downward(size_t index) { return move_left_downward(index) + 1; } inline bool is_left(size_t index) { return move_left_downward(move_upward(index)) == index; } inline bool is_right(size_t index) { return !is_left(index); } void add_value(vector<int>&tree, size_t base_offset, size_t index, int val) { size_t pos = base_offset + index; tree[pos] += val; while(pos != 0) { pos = move_upward(pos); tree[pos] += val; } } int find_value(const vector<int>&tree, size_t base_offset, size_t index) { size_t pos = base_offset + index; int invalid = 0; while(pos != 0) { size_t parent = move_upward(pos); if(is_left(pos)) invalid += tree[parent] - tree[pos]; pos = parent; } return tree[0] - invalid; } int find_value(const vector<int>&tree, size_t base_offset, size_t index_min, size_t index_max) { if(index_max < index_min) swap(index_max, index_min); if(index_min == 0) return find_value(tree, base_offset, index_max); --index_min; return find_value(tree, base_offset, index_max) - find_value(tree, base_offset, index_min); } int main() { ifstream in("in.txt"); ofstream out("out.txt"); char c; in>>c; assert(c == 'J'); size_t area_size; in>>area_size; size_t total_size = tree_size(area_size); size_t base_offset = total_size - area_size; vector<int>tree(total_size, 0); while(in>>c) { if(c == 'M') { size_t index; int val; in>>index>>val; assert(1 <= index && index <= tree.size()); --index; add_value(tree, base_offset, index, val); }else if(c == 'C'){ size_t index_min, index_max; in>>index_min>>index_max; assert(1 <= index_min && index_min <= tree.size()); assert(1 <= index_max && index_max <= tree.size()); --index_min; --index_max; out<<find_value(tree, base_offset, index_min, index_max)<<endl; }else if(c == 'R') return 0; else assert(0); } } |
| CODE |
| #include<fstream> #include<vector> #include<cassert> using namespace std; size_t find_lowest_bit(size_t bits) { assert(bits != 0); size_t bit = 1; while(!(bits & bit)) bit <<= 1; return bit; } size_t move_to_next_higher_level(size_t index) //for move walk { size_t low_bit = find_lowest_bit(index); index &= ~low_bit; low_bit <<= 1; index += low_bit; return index; } size_t move_to_pre_higher_level(size_t index) //for count walk { size_t low_bit = find_lowest_bit(index); index &= ~low_bit; return index; } size_t tree_size_align(size_t size) { size_t tree_size = 1; while(tree_size < size) tree_size *= 2; return tree_size; } void move_people(vector<int>&tree, size_t index, int people) { size_t size = tree.size() - 1; while(index != size) { tree[index] += people; index = move_to_next_higher_level(index); } } int count_people(const vector<int>&tree, size_t index) { int people = 0; while(index != 0) { people += tree[index]; index = move_to_pre_higher_level(index); } return people; } int count_people(const vector<int>&tree, size_t index_min, size_t index_max) { if(index_max < index_min) swap(index_min, index_max); if(index_min != 1) return count_people(tree, index_max) - count_people(tree, index_min-1); else return count_people(tree, index_max); } int main() { ifstream in("in.txt"); ofstream out("out.txt"); vector<int>tree; char c; while(in>>c) { switch(c) { case 'J': { size_t size; in>>size; //alloc one more int so that we can start at index 1 tree.resize(tree_size_align(size) + 1, 0); } break; case 'R': return 0; case 'M': { size_t index; int people; in>>index>>people; move_people(tree, index, people); } break; case 'C': { size_t index_min, index_max; in>>index_min>>index_max; out<<count_people(tree, index_min, index_max)<<endl; } break; } } } |