250pt
题意:给定n把锁,第i轮每间隔i个打开一个木有打开的。问最后打开的事几
思路:直接vector模拟
code:
1 #line 7 "LockersDivOne.cpp" 2 #include <cstdlib> 3 #include <cctype> 4 #include <cstring> 5 #include <cstdio> 6 #include <cmath> 7 #include <algorithm> 8 #include <vector> 9 #include <string> 10 #include <iostream> 11 #include <sstream> 12 #include <map> 13 #include <set> 14 #include <queue> 15 #include <stack> 16 #include <fstream> 17 #include <numeric> 18 #include <iomanip> 19 #include <bitset> 20 #include <list> 21 #include <stdexcept> 22 #include <functional> 23 #include <utility> 24 #include <ctime> 25 using namespace std; 26 27 #define PB push_back 28 #define MP make_pair 29 30 #define REP(i,n) for(i=0;i<(n);++i) 31 #define FOR(i,l,h) for(i=(l);i<=(h);++i) 32 #define FORD(i,h,l) for(i=(h);i>=(l);--i) 33 34 typedef vector<int> VI; 35 typedef vector<string> VS; 36 typedef vector<double> VD; 37 typedef long long LL; 38 typedef pair<int,int> PII; 39 40 class LockersDivOne 41 { 42 public: 43 int get(int n){ 44 vector<int> a, b; 45 for (int i = 0; i < n; ++i) 46 a.push_back(i); 47 int res = 0; 48 for (int i = 2; ; ++i){ 49 if (a.size() == 0) break; 50 b.clear(); 51 for (int j = 0; j < a.size(); j++) 52 if (j % i == 0) res = a[j] + 1; 53 else b.push_back(a[j]); 54 a = b; 55 } 56 return res; 57 58 } 59 int lastOpened(int N) 60 { 61 return get(N); 62 } 63 };
500pt
题意:A和B两个人玩汉诺塔,其中A移动汉诺塔用最快的方法,移动的步数是2^n-1步,而B用的方法可以保证每种状态恰好被访问到一次,移动的步数是3^n-1。两个人移动的伪代码都给定,问第一个人移动K步后的configuration,按照第二个人的方法需要移动多少步。
思路:先算出最终的状态。然后根据最终的状态用递归算出答案。
code:
1 #line 7 "HanoiGoodAndBad.cpp" 2 #include <cstdlib> 3 #include <cctype> 4 #include <cstring> 5 #include <cstdio> 6 #include <cmath> 7 #include <algorithm> 8 #include <vector> 9 #include <string> 10 #include <iostream> 11 #include <sstream> 12 #include <map> 13 #include <set> 14 #include <queue> 15 #include <stack> 16 #include <fstream> 17 #include <numeric> 18 #include <iomanip> 19 #include <bitset> 20 #include <list> 21 #include <stdexcept> 22 #include <functional> 23 #include <utility> 24 #include <ctime> 25 using namespace std; 26 27 #define PB push_back 28 #define MP make_pair 29 30 #define REP(i,n) for(i=0;i<(n);++i) 31 #define FOR(i,l,h) for(i=(l);i<=(h);++i) 32 #define FORD(i,h,l) for(i=(h);i>=(l);--i) 33 34 typedef vector<int> VI; 35 typedef vector<string> VS; 36 typedef vector<double> VD; 37 typedef long long LL; 38 typedef pair<int,int> PII; 39 int thr[20]; 40 41 class HanoiGoodAndBad 42 { 43 public: 44 int dd, ans; 45 int H[3][25]; 46 int top[3]; 47 void solve_Dave(int a, int c, int b, int n){ 48 if(n > 0){ 49 if (dd == 0) return; 50 solve_Dave(a, b, c, n-1); 51 if (dd == 0) return; 52 H[c][++top[c]] = n; 53 H[a][top[a]--] = 0; 54 --dd; 55 solve_Dave(b, c, a, n-1); 56 } 57 } 58 void solve_Earl(int a, int c, int b, int n){ 59 if (n == 0) return; 60 int P = 0; 61 if (H[1][top[1]] == n) P = 1; 62 if (H[2][top[2]] == n) P = 2; 63 top[P]--; 64 if (P == c){ 65 ans += 2 * thr[n-1]; 66 solve_Earl(a, c, b, n-1); 67 } 68 if (P == b){ 69 ans += thr[n-1]; 70 solve_Earl(c, a, b, n-1); 71 } 72 if (P == a) solve_Earl(a, c, b, n-1); 73 } 74 int moves(int N, int Dave) 75 { 76 dd = Dave; 77 memset(top, 0, sizeof(top)); 78 memset(H, 0, sizeof(H)); 79 for (int i = N; i >= 1; --i) H[0][++top[0]] = i; 80 solve_Dave(0, 2, 1, N); 81 ans = 0; 82 for (int i = 0; i < 3; ++i) 83 for (int j = 1; j <= top[i]/ 2; ++j) 84 swap(H[i][j], H[i][top[i]-j+1]); 85 thr[0] = 1; 86 for (int i = 1; i <= 19; ++i) thr[i] = thr[i-1] * 3; 87 solve_Earl(0, 2, 1, N); 88 return ans; 89 } 90 };