Я, , Свинодемон, , [0][1][2][3][4][5][6] e2-e2, , e2-e2, , e2-e2, , e2-e2, , e2-e2, , e2-e2, , e2-e2, , e2-e2, , e2-e2, , e2-e2, , e2-e2, , e2-e2, , e2-e2, , e2-e2, , e2-e2, , e2-e2, , e2-e2, , e2-e2, , e2-e2, , e2-e2, , e2-e2, , шарфан, , e2-e2, , e2-e2, , #include <iostream> #include <string> #include <vector> #include <cstdlib> using namespace std; vector<int> field(16); string way; int zero; void cornerConflict(); int findNum(int number) { for(int i = 0; i < 16; i++) { if(field == number) return i; } return -1; } int X(int num) { return findNum(num) % 4; } int Y(int num) { return findNum(num) / 4; } vector<int> ReadData() { vector<int> data(16); for(int i = 0; i < 16; i++) { cin >> data; } return data; } bool zeroUp() { if(zero / 4 == 0) return false; swap(field[zero], field[zero - 4]); zero -= 4; way.push_back('u'); return true; } bool zeroDown() { if(zero / 4 == 3) return false; swap(field[zero], field[zero + 4]); zero += 4; way.push_back('d'); return true; } bool zeroLeft() { if(zero % 4 == 0) return false; swap(field[zero], field[zero - 1]); zero -= 1; way.push_back('l'); return true; } bool zeroRight() { if(zero % 4 == 3) return false; swap(field[zero], field[zero + 1]); zero += 1; way.push_back('r'); return true; } bool rightReturn() { if(zero % 4 == 3) return false; zeroRight(); zeroUp(); zeroUp(); zeroLeft(); return true; } bool leftReturn() { if(zero % 4 == 0) return false; zeroLeft(); zeroUp(); zeroUp(); zeroRight(); return true; } bool downReturn(int how) { if(!zeroDown()) return false; if(how == 1) { zeroRight(); zeroRight(); } else { zeroLeft(); zeroLeft(); } zeroUp(); return true; } void ZeroWorkWithNum(int number) { if(Y(number) == 3) { if(zero / 4 == 3) { zeroRight(); zeroUp(); } else { while(zero / 4 != 2) { zeroDown(); } } while(X(number) < zero % 4) { zeroLeft(); } while(X(number) > zero % 4) { zeroRight(); } zeroDown(); } else { while(Y(number) + 1 != zero / 4) { if(zero / 4 <= Y(number)) zeroDown(); else zeroUp(); } while(X(number) < zero % 4) { zeroLeft(); } while(X(number) > zero % 4) { zeroRight(); } } } bool NumToPos(int number, int position) { if(number == field[position]) return true; ZeroWorkWithNum(number); if(position % 4 < zero % 4) { zeroLeft(); zeroUp(); while(position % 4 < zero % 4) { zeroRight(); downReturn(-1); } zeroRight(); if(field[position] == number) { zeroDown(); zeroLeft(); return true; } if(zeroUp()) { zeroLeft(); zeroDown(); while(field[position] != number) { rightReturn(); zeroDown(); } } else zeroDown(); } else if(position % 4 > zero % 4) { zeroRight(); zeroUp(); while(position % 4 > zero % 4) { zeroLeft(); downReturn(1); } zeroLeft(); if(position % 4 == 1) { downReturn(1); if(zeroUp()) { zeroLeft(); zeroDown(); while(field[position] != number) { rightReturn(); zeroDown(); } } else zeroDown(); } if(field[position] == number) { zeroDown(); zeroRight(); return true; } if(zeroUp()) { zeroRight(); zeroDown(); while(field[position] != number) { leftReturn(); zeroDown(); } } else zeroDown(); } else if(zero % 4 == 3) { while(field[position] != number) { leftReturn(); zeroDown(); } } else { while(field[position] != number) { rightReturn(); zeroDown(); } } return true; } void buildRow(int n) { NumToPos(n, n - 1); NumToPos( n + 1, n); NumToPos(n + 2, n + 2); if(field[n + 1] == n + 3) { cornerConflict(); } else { NumToPos(n + 3, n + 6); } zeroLeft(); zeroUp(); zeroUp(); zeroRight(); zeroDown(); } bool solved() { for(int i = 0; i < 15; i++) { if(field != i + 1) return false; } return true; } void debugPrint() { for(int i = 0; i < (int)field.size(); i++) { cout << field << " "; } cout << endl << way << endl; } void Body() { bool temp = false; for(int i = 0; i < 4; i++) { if(field != i + 1) temp = true; } if(temp) buildRow(1); temp = false; for(int i = 4; i < 8; i++) { if(field != i + 1) temp = true; } if(temp) buildRow(5); /*NumToPos(13, 8); NumToPos(9, 9); zeroDown(); if(zero % 4 == 0) zeroRight(); while(zero % 4 > 1) zeroLeft(); zeroLeft(); zeroUp(); zeroRight(); NumToPos(14, 9); if(field[14] == 10) cornerConflict2(); else NumToPos(10, 10); zeroDown(); if(zero % 4 == 1) zeroRight(); while(zero % 4 > 2) zeroLeft(); zeroLeft(); zeroUp(); zeroRight(); while(true) { if(solved()) break; zeroRight(); if(solved()) break; zeroDown(); if(solved()) break; zeroLeft(); if(solved()) break; zeroUp(); }*/ //debugPrint(); } bool HasSolution() { int inv = 0; for(int i = 0; i < 16; i++) if(field) for(int j = 0; j < i; j++) if(field[j] > field) inv++; for(int i = 0; i < 16; i++) if(field == 0) inv += 1 + i / 4; return ((inv & 1) ? false : true); } void cornerConflict() { if(zero / 4 == 3) zeroUp(); while(zero % 4 < 3) zeroRight(); zeroUp(); zeroLeft(); zeroDown(); zeroRight(); zeroDown(); zeroLeft(); zeroUp(); zeroRight(); zeroUp(); zeroLeft(); zeroDown(); zeroRight(); zeroDown(); zeroLeft(); zeroUp(); zeroRight(); zeroDown(); zeroLeft(); zeroUp(); zeroUp(); zeroRight(); zeroDown(); zeroDown(); } #include <vector> #include <iostream> #include <queue> #include <algorithm> #include <set> using namespace std; class CField; bool cmp(const CField& b, const CField& c); class CField { vector<int> field; vector<char> way; int zero; public: CField(vector<int> _field) { field = _field; for(int i = 0; i < (int) field.size(); i++) { if(field == 0) { zero = i; } } } CField(vector<int> _field, vector<char> _way) { field = _field; way = _way; for(int i = 0; i < (int) field.size(); i++) { if(field == 0) { zero = i; } } } ~CField() { } vector<char> getWay() { return way; } vector<int> getF() { return field; } int getZero() { return zero; } bool FirstRow() const { for(int i = 0; i < 4; i++) { if(field != i + 1) return false; } return true; } bool SecondRow() const { for(int i = 4; i < 8; i++) { if(field != i + 1) return false; } return true; } int simpleDistance() const { int sum = 0; for(int i = 0; i < 16; i++) { if(field != 0) { sum += abs((i / 4) - (field - 1) / 4); sum += abs((i % 4) - (field - 1) % 4); } else { sum += abs((i / 4) - 15 / 4); sum += abs((i % 4) - 15 % 4); } } return sum; } int distance() const { int sum = 0; if(field[15] != 12 && field[15] != 15) { sum += 2; } sum = simpleDistance() + sum + findConflicts(); return sum; } bool solved() { for(int i = 0; i < 15; i++) { if(field != i + 1) { return false; } } return true; } int findConflicts() const { int sum = 0; vector<bool> confl(16, false); vector<int> fieldTemp = field; for(int i = 0; i < 16; i++) { if(fieldTemp % 4 == (i + 1) % 4 && fieldTemp != 0) { if(i + 1 < fieldTemp) { int k = i; k += 4; while(k < 15) { if((i + 1) % 4 == fieldTemp[k] % 4 && fieldTemp[k] < fieldTemp && fieldTemp[k] != 0) { sum += 2; confl[k] = true; confl = true; } k += 4; } } } if((fieldTemp - 1) / 4 == i / 4 && fieldTemp != 0) { if(i + 1 < fieldTemp) { int k = i; k += 1; while(k < ((i / 4 + 1) * 4)) { if(i / 4 == (fieldTemp[k] - 1) / 4 && fieldTemp[k] < fieldTemp && fieldTemp[k] != 0) { sum += 2; confl[k] = true; confl = true; } k += 1; } } } } if(field[2] == 3 && field[3] != 4 && !confl[2]) sum += 2; if(field[7] == 8 && field[3] != 4 && !confl[7]) sum += 2; if(field[8] == 9 && field[12] != 13 && !confl[8]) sum += 2; if(field[13] == 14 && field[12] != 13 && !confl[13]) sum += 2; if(field[1] == 2 && field[0] != 1 && !confl[1]) sum += 2; if(field[4] == 5 && field[0] != 1 && !confl[4]) sum += 2; if(!FirstRow()) sum += 16; else if(!SecondRow()) sum += 8; return sum; } bool operator < (const CField &c) const { return field < c.field; } bool HasSolution() { int inv = 0; for(int i = 0; i < 16; i++) if(field) for(int j = 0; j < i; j++) if(field[j] > field) inv++; for(int i = 0; i < 16; i++) if(field == 0) inv += 1 + i / 4; return ((inv & 1) ? false : true); } vector<CField> nextSteps() { vector<CField> ns; if(zero % 4 != 0) { swap(field[zero], field[zero - 1]); CField a(field, way); a.way.push_back('l'); a.zero = zero - 1; ns.push_back(a); swap(field[zero], field[zero - 1]); } if(zero % 4 != 3) { swap(field[zero], field[zero + 1]); CField a(field, way); a.way.push_back('r'); a.zero = zero + 1; ns.push_back(a); swap(field[zero], field[zero + 1]); } if(zero / 4 < 3) { swap(field[zero], field[zero + 4]); CField a(field, way); a.way.push_back('d'); a.zero = zero + 4; ns.push_back(a); swap(field[zero], field[zero + 4]); } if(zero / 4 > 0) { swap(field[zero], field[zero - 4]); CField a(field, way); a.way.push_back('u'); a.zero = zero - 4; ns.push_back(a); swap(field[zero], field[zero - 4]); } return ns; } }; bool cmp(const CField &b, const CField &c) { return b.distance() < c.distance(); } CField ReadData1() { vector<int> bones; int number; for(int i = 0; i < 16; i++) { cin >> number; bones.push_back(number); } CField data = CField(bones); return data; } vector<char> Body1(CField field, CField& answer, int& flag) { vector<char> result; set<vector<int> > visited; vector<CField> nextSteps; queue<CField> lookAtMe; lookAtMe.push(field); if(field.solved()) { flag++; answer = field; result = field.getWay(); return result; } while(true) { CField temp = lookAtMe.front(); /*cout << lookAtMe.size() << endl; cout << "***" << temp.distance() << endl; char ololo; ololo = getchar();*/ lookAtMe.pop(); if(visited.find(temp.getF()) == visited.end()) { nextSteps = temp.nextSteps(); sort(nextSteps.begin(), nextSteps.end(), cmp); bool ins = false; for(int j = 0; j < (int) nextSteps.size(); j++) { if(!ins && (visited.find(nextSteps[j].getF()) == visited.end())) { int min = nextSteps[j].distance(); for(int i = 0; i < (int) nextSteps.size(); i ++) { if(nextSteps.distance() <= min && (visited.find(nextSteps.getF()) == visited.end())) { lookAtMe.push(nextSteps); if(flag == 0 && nextSteps.FirstRow()) { flag = 1; answer = nextSteps; return nextSteps.getWay(); } if(flag == 1 && nextSteps.FirstRow() && nextSteps.SecondRow()) { flag = 2; answer = nextSteps; return nextSteps.getWay(); } if(nextSteps.solved()) { flag++; answer = temp; result = nextSteps.getWay(); return result; } } } ins = true; } } } visited.insert(temp.getF()); } return result; } int main() { field = ReadData(); zero = findNum(0); if(HasSolution()) { cout << "YES" << endl; Body(); } else { cout << "NO" << endl; } vector<char> result; CField data(field); CField answer = data; int flag = 0; if(data.HasSolution()) { while(flag != 2) { Body1(answer, answer, flag); //cout << flag << endl; } result = Body1(answer, answer, flag); for(int i = 0; i < (int) result.size(); i++) { way.push_back(result); } cout << way << endl; } return 0; } e2-e2, , гороскоп на сегодня Пожалуй, лучшее, что сегодня можно сделать, – это не делать ничего вообще. Естественно, по возможности. Увы, звезды гороскопа будут склонять к хаосу и в мыслях, и делах, и в общении. Ну а с учетом того, что эмоциональный фон дня обещает быть очень напряженным, очевидно, что хаос может стать разрушительным. В такие дни люди часто совершают нелогичные поступки, ссорятся из-за пустяков, теряют осторожность и забывают о чувстве меры. Чтобы подобного с вами не произошло, дайте своим нервам отдохнуть, посвятив этот день чему-нибудь простому, спокойному и по возможности позитивному. Свинодемон, , [0][1][2][3][4][5][6] Отметиться |