标签:
There are numMales males and numFemales females arranged in a circle. Starting from a given point, you count clockwise and remove the K‘th person from the circle (where K=1 is the person at the current point, K=2 is the next person in the clockwise direction, etc...). After removing that person, the next person in the clockwise direction becomes the new starting point. After repeating this procedure numFemales times, there are no females left in the circle.
Given numMales, numFemales and K, your task is to return what the initial arrangement of people in the circle must have been, starting from the starting point and in clockwise order.
For example, if there are 5 males and 3 females and you remove every second person, your return String will be "MFMFMFMM".
Number of | People Remaining Rounds | (in initial order) ---------------+----------------- 0 | mFFMMFFMFM 1 | MF_mMFFMFM 2 | MF_MM_fMFM 3 | MF_MM_FM_m 4 | M__mM_FM_M 5 | M__MM__m_M
This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. (c)2003, TopCoder, Inc. All rights reserved.
1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 #include <ctime> 5 #include <iostream> 6 #include <algorithm> 7 #include <set> 8 #include <vector> 9 #include <sstream> 10 #include <typeinfo> 11 #include <fstream> 12 13 using namespace std; 14 char s[2000] ; 15 vector<int> g ; 16 int n ; 17 int k ; 18 19 void dead (int id , int ans , int m) 20 { 21 for (int i = ans ; i <= n ; i ++) { 22 k = m % i ; 23 id = (id + k) % i ; 24 } 25 // printf ("id = %d\n" , id ) ; 26 g.push_back (id) ; 27 } 28 29 void solve (int fmale , int m) 30 { 31 dead (0 , 2 , m ) ; 32 for (int i = 2 ; i <= n ; i ++) { 33 k = m % i ; 34 int id = (0 + k) % i ; 35 if (id - 1 < 0) id = id - 1 + i ; 36 else id -- ; 37 dead (id , i + 1 , m ) ; 38 } 39 reverse (g.begin () , g.end ()) ; 40 // for (int i :g ) printf ("%d " , i) ; puts ("") ; 41 for (int i = 0 ; i < n ; i ++) { 42 if (i < fmale) s[g[i]] = ‘F‘ ; 43 else s[g[i]] = ‘M‘ ; 44 } 45 s[n] = ‘\0‘ ; 46 } 47 48 class PeopleCircle { 49 public: 50 string order(int male , int fmale , int m) { 51 // printf ("\nmale=%d\nfmale=%d\nm=%d\n" , male , fmale , m) ; 52 g.clear () ; 53 n = male + fmale ; 54 solve (fmale , m) ; 55 return s; 56 } 57 }; 58 59 // CUT begin 60 ifstream data("PeopleCircle.sample"); 61 62 string next_line() { 63 string s; 64 getline(data, s); 65 return s; 66 } 67 68 template <typename T> void from_stream(T &t) { 69 stringstream ss(next_line()); 70 ss >> t; 71 } 72 73 void from_stream(string &s) { 74 s = next_line(); 75 } 76 77 template <typename T> 78 string to_string(T t) { 79 stringstream s; 80 s << t; 81 return s.str(); 82 } 83 84 string to_string(string t) { 85 return "\"" + t + "\""; 86 } 87 88 bool do_test(int numMales, int numFemales, int K, string __expected) { 89 time_t startClock = clock(); 90 PeopleCircle *instance = new PeopleCircle(); 91 string __result = instance->order(numMales, numFemales, K); 92 double elapsed = (double)(clock() - startClock) / CLOCKS_PER_SEC; 93 delete instance; 94 95 if (__result == __expected) { 96 cout << "PASSED!" << " (" << elapsed << " seconds)" << endl; 97 return true; 98 } 99 else { 100 cout << "FAILED!" << " (" << elapsed << " seconds)" << endl; 101 cout << " Expected: " << to_string(__expected) << endl; 102 cout << " Received: " << to_string(__result) << endl; 103 return false; 104 } 105 } 106 107 int run_test(bool mainProcess, const set<int> &case_set, const string command) { 108 int cases = 0, passed = 0; 109 while (true) { 110 if (next_line().find("--") != 0) 111 break; 112 int numMales; 113 from_stream(numMales); 114 int numFemales; 115 from_stream(numFemales); 116 int K; 117 from_stream(K); 118 next_line(); 119 string __answer; 120 from_stream(__answer); 121 122 cases++; 123 if (case_set.size() > 0 && case_set.find(cases - 1) == case_set.end()) 124 continue; 125 126 cout << " Testcase #" << cases - 1 << " ... "; 127 if ( do_test(numMales, numFemales, K, __answer)) { 128 passed++; 129 } 130 } 131 if (mainProcess) { 132 cout << endl << "Passed : " << passed << "/" << cases << " cases" << endl; 133 int T = time(NULL) - 1434017957; 134 double PT = T / 60.0, TT = 75.0; 135 cout << "Time : " << T / 60 << " minutes " << T % 60 << " secs" << endl; 136 cout << "Score : " << 600 * (0.3 + (0.7 * TT * TT) / (10.0 * PT * PT + TT * TT)) << " points" << endl; 137 } 138 return 0; 139 } 140 141 int main(int argc, char *argv[]) { 142 cout.setf(ios::fixed, ios::floatfield); 143 cout.precision(2); 144 set<int> cases; 145 bool mainProcess = true; 146 for (int i = 1; i < argc; ++i) { 147 if ( string(argv[i]) == "-") { 148 mainProcess = false; 149 } else { 150 cases.insert(atoi(argv[i])); 151 } 152 } 153 if (mainProcess) { 154 cout << "PeopleCircle (600 Points)" << endl << endl; 155 } 156 return run_test(mainProcess, cases, argv[0]); 157 } 158 // CUT end
题意:n个人围成一圈,从编号为0的人开始报数1,后面的依次报2,3……当报道m时,该人离开圈子,他后面的一个人重新从1开始报数,以此类推……游戏最终会只有一个人留下来。这道题中我们需要得到的是每次离开之人的编号。(总人数n已知,m已知)。-------- 约瑟夫环问题,几乎是每个acmer的入门套餐。
上学期的时候,貌似用链表模拟做过,后来又用数学方法求过,但并不是很理解,如今又碰到了,便打算好好写份约瑟夫环报告。
从第一轮开始:
0 1 2 3 4 5 …… (n - 2) (n - 1) 现在有n个人
标签:
原文地址:http://www.cnblogs.com/get-an-AC-everyday/p/4572500.html