HDU 5355 Cake (the original error code has been updated), hdu5355
Cake
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Special Judge
Problem DescriptionThere are M Soda and today is their birthday. 1 -St soda has prepared N Cakes with size 1, 2 ,..., N . Now 1 -St soda wants to divide the cakes M Parts so that the total size of each part is equal.
Note that you cannot divide a whole cake into small pieces that is each cake must be complete in M Parts. Each cake must belong to exact one M Parts.
InputThere are multiple test cases. The first line of input contains an integer T , Indicating the number of test cases. For each test case:
The first contains two integers N And M (1 ≤ n ≤ 105,2 ≤ m ≤ 10) , The number of cakes and the number of soda.
It is guaranteed that the total number of soda in the input doesn't exceed 1000000. The number of test cases in the input doesn't exceed 1000.
OutputFor each test case, output "YES" (without the quotes) if it is possible, otherwise output "NO" in the first line.
If it is possible, then output M Lines denoting M Parts. The first number Si Of I -Th line is the number of cakes in I -Th part. Then Si Numbers follow denoting the size of cakes in I -Th part. If there are multiple solutions, print any of them.
Sample Input
41 25 35 29 3
Sample Output
NOYES1 52 1 42 2 3NOYES3 1 5 93 2 6 73 3 4 8
Source2015 Multi-University Training Contest 6 /******************************** **************************************** *********/
This question is a bit pitfall. spj encountered a problem during the competition, and the result was a water question with an AC rate of up to 50%. After the competition, spj was updated, so that most of the original AC code is WA. Now I want to talk about a method that can communicate with AC. I mentioned that another method will be put later, but I don't know what went wrong, it has been TLE, so I cannot share it with you. Sorry.
N sizes: 1, 2, 3 ,..., N cake requires you to divide it into m parts, and the sum of all the cakes in each part is the same. If there is a solution, output "YES" and give the number and size of each cake, otherwise, "NO" is output"
For example, n = 5, m = 3, that is, the size of each of the five cakes is 1, 2, 3, 3, and 5, respectively. The solution can be the first one, the size is 5, the second is two cakes, the size is 1, 4, and the third is two cakes, the size is 2, 3. In this way, the sum of each part is 5 to meet the requirements of the questions.
Put the problem solving Report of the person who asked the question
Solution: There are two solutions to this problem: ① the sum of the sizes of all cakes cannot be divisible by m; ② the sum of the sizes of each cake cannot be less than the maximum n of the cake size, that is, sum/m> = n, which is converted to n * m <= sum. You can also substitute sum into n> = 2 * S-1.
Then there is a solution. If there is a solution, the sum of the size of each cake is known, that is, sum/m. Then we can know that the minimum n value is 2 * s-1. For example, n = 5, m = 3,
5 3
1 5
2 4 1
2 3 2
M-1 indicates that n itself can be a group, the other two groups, a positive increase, a reverse decline, must be able to make up n, of course, this is an odd number of circumstances
However, this method is not parity. The above is just a description. In fact, we need to divide the allocation method into two parts, one is k 2 * m, and the other is the remaining part. Let's take a look at n = 23, m = 6 this set of data, the previous AC code is generally unable to pass this set of data
23 6
YES
3 11 12 23
4 10 1 13 22
4 9 2 14 21
4 8 3 15 20
4 7 4 16 19
4 6 5 17 18
Use (n-m * 2 + 1) % (m * 2) + m * 2-1 to calculate the size of the pink part of the data, and then use the second enumeration to find the correct cake size, the remaining green part is k 2 * m parts. The small number of this part is positive increasing, and the large number is backward decreasing, so it must meet the requirements. To make it more intuitive, put n = 100, m = 5 Data
100 5
YES
20 10 1 11 100 12 99 13 98 14 97 15 96 16 95 17 94 18 93 19 92
20 9 2 20 91 21 90 22 89 23 88 24 87 25 86 26 85 27 84 28 83
20 8 3 29 82 30 81 31 32 79 33 78 34 77 35 76 36 75 37 74
20 7 4 38 73 39 72 40 71 41 70 42 69 68 44 67 45 66 46 65
20 6 5 47 64 48 63 49 62 61 51 60 52 53 58 54 57 55 56
If you still do not understand the AC code, I will reply as soon as possible. Thank you.
# Include <stdio. h> # include <string. h> # include <stdlib. h> # include <queue> # include <math. h> # include <vector> # include <map> # include <set> # include <cmath> # include <string> # include <algorithm> # include <iostream> # define exp 1e-10 # define ll _ int64using namespace std; const int N = 100005; const int inf = 1000000000; const int mod = 1000000007; int solve () {_ int64 n, m; int I, j, k, c, s, d, r, w [32]; set <int> v; set <int>: iterator it; scanf ("% I64d % I64d", & n, & m); if (n + 1) * n/2) % m | m * 2-1> n) return puts ("NO "); c = (n-m * 2 + 1) % (m * 2) + m * 2-1, // The cake distribution method can be divided into two parts, the first part contains at least M-1 s = c * (c + 1)/(m * 2), // and k 2 * m must be followed, then, the extra part is stored in the first part. d = (n-c)/(m * 2); // (n-m * 2 + 1) % (m * 2) + m * 2-1 puts ("YES"); for (I = 1; I <= c; I ++) v. insert (I); for (j = 0, k = c + 1; j <m; j ++, putchar ('\ n ')) {for (c = r = 0; r <s;) // The sum of {it = v. upper_bound (s-r); // find the cake size closest to s by means of binary search. r ++ = w [c ++] = * -- it; v. erase (it);} printf ("% d", c + d * 2); // c + d * 2 indicates the number of cakes in each group, d is k 2 * m k for (I = 0; I <c; I ++) printf ("% d", w [I]) mentioned in the question; for (I = 0; I <d; I ++) printf ("% d", k ++, n --); // In fact, the code is difficult to explain, further understanding must be made based on the above example.} int main () {int t; for (scanf ("% d", & t); t --; solve ());}
// The data of this question is updated. The above method is AC code, but the following method is no longer AC. Leave this as an example for reference.
N sizes: 1, 2, 3 ,..., N cake requires you to divide it into m parts, and the sum of all the cakes in each part is the same. If there is a solution, output "YES" and give the number and size of each cake, otherwise, "NO" is output"
For example, n = 5, m = 3, that is, the size of each of the five cakes is 1, 2, 3, 3, and 5, respectively. The solution can be the first one, the size is 5, the second is two cakes, the size is 1, 4, and the third is two cakes, the size is 2, 3. In this way, the sum of each part is 5 to meet the requirements of the questions.
Put the problem solving Report of the person who asked the question
Solution: There are two solutions to this problem: ① the sum of the sizes of all cakes cannot be divisible by m; ② the sum of the sizes of each cake cannot be less than the maximum n of the cake size, that is, sum/m> n, which is converted to n * m <sum.
Then there is a solution. If there is a solution, the sum of the size of each cake is known, that is, sum/m, then we only need to fill in the sum of the sizes of each part of the cake from the large to the small violent enumeration. For example, n = 5, m = 3, that is, the size of each of the five cakes is 1, 2, 3, 3, and 5, respectively. The first one is the largest one, that is, 5 is the size that meets the requirements of the first cake. The second cake also obtains the largest cake that has not been obtained first, and then adds the cake whose sum of the values does not exceed the average value in sequence, that is, put 4 first and then 1; the same is true for the third. In this way, the sum of each part is still 5 to meet the requirements of the questions.
For details, see the code
#include<stdio.h>#include<string.h>#include<stdlib.h>#include<queue>#include<math.h>#include<vector>#include<map>#include<set>#include<cmath>#include<string>#include<algorithm>#include<iostream>#define exp 1e-10#define ll __int64using namespace std;const int N = 100005;const int inf = 1000000000;const int mod = 1000000007;bool v[N];int s[11][N/2];int main(){ int t,i,j; __int64 sum,n,m,ans; scanf("%d",&t); while(t--) { memset(v,true,sizeof(v)); memset(s,0,sizeof(s)); scanf("%I64d%I64d",&n,&m); sum=(1+n)*n/2; if(sum%m||n*m>sum) { puts("NO"); continue; } puts("YES"); sum=sum/m; for(i=1;i<=m;i++) { ans=0; for(j=n;j>=1;j--) { if(v[j]&&ans+j<=sum) { ans+=j; s[i][++s[i][0]]=j; v[j]=false; } if(ans==sum) break; } } for(i=1;i<=m;i++) { for(j=0;j<s[i][0];j++) printf("%d ",s[i][j]); printf("%d\n",s[i][j]); } } return 0;}
Thank you for your comments.
Cainiao growth notes
Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.