Joseph
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 1652 Accepted Submission(s): 1031
Suppose that there are k good guys and k bad guys. In the circle the first k are good guys and the last k bad guys. You have to determine such minimal m that all the bad guys will be executed before the first good guy.
Ideas:
If you use the list of C++STL to do this question, it will time out. I have not thought of how to use the list in the AC question. The method used here is to simulate the process of a linked list. The idea is simply to enumerate the values of m one by one. Output m until the conditions are met, but if you use a list, every time you delete a list element, you need to traverse the entire list. Generally, thousands of times of traversal will take a lot of time. Therefore, the way to not time out is to skip the traversal. , directly by finding the element after + m, and then deleting it, every time you enumerate an m value, you only need to traverse k elements, and the time will be much faster; there is another point to pay attention to, similar to the future. The question should be habitually adding an array of punching tables to avoid the time-out of multiple input times of the judgment machine. The code is given below (the simulation method will be given below the code)
#include<iostream> #include<string> #include<cstring> #include<cstdio> #include<cstdlib> #include<time.h> #include<cmath> #include<stack> #include<list> #include<queue> #include<map> #define E exp(1) #define PI acos(-1) #define mod (ll)(1e9+9) #define INF 0x3f3f3f3f; //#define _CRT_SECURE_NO_WARNINGS //#define LOCAL using namespace std; typedef long long ll; typedef long double lb; int main(void) { #ifdef LOCAL freopen("data.in.txt", "r", stdin); freopen("data.out.txt", "w", stdout); #endif //The above content can be ignored, it is the spare code for doing the question int k,tp, cnt, num, flag, table[15]; memset(table, 0, sizeof(table)); while (scanf("%d", &k) != EOF) { if (k == 0) break; if (table[k] != 0) { //The array of the table is to save the obtained answer, printf("%d\n", table[k]); //Determine the next multiple sets of data measured by the machine, if it is the requested data continue; //Then it can be output directly } int m = k + 1, cur; // Nothing related to the linked list is used here, just at the end of the for loop, //Add an if (to the last value) to let i = 0 traverse again, //This is like traversing a linked list while (1) { num = 2*k; flag = 0; why = 1; while (num > k) { // The value of this tp is the number of times the current traversed value cur continues to count, //In fact, there is no problem in changing tp to m, //It's just that once the value of m is large, it will take a lot of time //For example, m = 10 to count in an array with 6 elements, //The result of reporting 10 times and reporting 4 times is the same, tp = m % num == 0 ? num : m % num //The value of the next cur here is obtained through two situations, the first is after the number of tp is reported //If there is no more than the current number of elements, you can directly +tp // If it exceeds, find the next cur through the complementary relationship if (cur + tp - 1 > num) { cur = tp - (num - cur)-1; //cur for the complementary relationship } else cur = cur + tp - 1; if (cur <= k) { flag = 1; break; } else num--; } if (flag) { m++; //Here is a pruning code when enumerating m, if the result of the first report // Less than or equal to the value of K, then this number does not need to be tried, directly use the current enumeration value //Add to a value greater than k and then try if (m % (2 * k) <= k && m % (2 * k) != 0) { m += (k - m % (2 * k) + 1); } } else{ table[k] = m; printf("%d\n", m); break; } } } //system("pause"); return 0; }
The simulation process here is roughly like this:
When m = 5 , k = 3
1 2 3 4 5 6 After reporting the number 5, according to the method of the linked list, the element 5 is deleted, but this is not the case, but the position of 5 is given to 6.
The result is this:
1 2 3 4 5
Then there are currently 5 elements, find tp according to the method in the code and start counting from the element 5, cur will be the element 4, then the position of the element 4 is set to 5 (that is, the previous element of the element to be deleted) ), the deletion process is very simple, that is, set a num = 2*k before the traversal; as long as num-- can not continue to traverse the numbers of the array larger than num;
Then the result is 1 2 3 4 , continue to count, and finally get cur = 3, at this time num==k then you can exit the loop;