Problem Description
Today, Soda has learned a sequence whose n-th (n≥1) item is 3n(n−1)+1. Now he wants to know if an integer m can be represented as the sum of some items of that sequence. If possible, what are the minimum items needed? For example, 22=19+1+1+1=7+7+7+1.
Input
There are multiple test cases. The first line of input contains an integer T (1≤T≤104), indicating the number of test cases. For each test case: There's a line containing an integer m (1≤m≤109).
Output
For each test case, output −1 if m cannot be represented as the sum of some items of that sequence, otherwise output the minimum items needed.
Sample Input
10 1 2 3 4 5 6 7 8 22 10
Sample Output
1 2 3 4 5 6 1 2 4 4
Source
对于这种题,首先一开始就要对给出的公式进行研究,从这里入手是正道。
分析公式 3n(n−1)+1 ,若给出一个数n,假设要k个3n(n−1)+1加起来得到n,即 3n(n-1)k+k=n,注意到3n(n-1)k是6的倍数,那么求的是满足(n-k)%6==0的最小的k。还有就是要注意到1、2要特判,即k要从3开始枚举
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 #include<cmath> 7 #include<stdlib.h> 8 #include<map> 9 using namespace std; 10 #define N 20000 11 int num[N]; 12 int n; 13 void init(){ 14 for(int i=1;i<N;i++){ 15 num[i]=3*i*(i-1)+1; 16 } 17 } 18 bool check1(){ 19 for(int i=1;i<N;i++){ 20 if(num[i]==n) 21 return true; 22 } 23 return false; 24 } 25 bool check2(){ 26 int j=N-1; 27 for(int i=1;i<N;i++){ 28 while(num[i]+num[j]>n && j>0) j--; 29 if(num[i]+num[j]==n && j>0){ 30 return true; 31 } 32 } 33 return false; 34 } 35 int main() 36 { 37 init(); 38 int t; 39 scanf("%d",&t); 40 while(t--){ 41 42 scanf("%d",&n); 43 if(check1()){ 44 printf("1 "); 45 } 46 else if(check2()){ 47 printf("2 "); 48 } 49 else{ 50 for(int i=3;i<10;i++){ 51 if((n-i)%6==0){ 52 printf("%d ",i); 53 break; 54 } 55 } 56 } 57 } 58 return 0; 59 }