Mean:
Description: An array containing non-negative integers (N in length) is used to find the maximum multiple of 3 consisting of these numbers. If not, impossible is output.
Analyze:
The first thing that comes to mind is direct violence. This is the dumbest method. If there is a large amount of data, it must be TLE.
Directly use brute force to generate all the combinations, which are 2 ^ N. Compare and judge each number. It takes O (n) time, because N may be relatively large, comparison of each bit is required.
The total time complexity is O (n * 2 ^ N ).
So what should we do?
First, let's learn a few mathematical knowledge:
1) if the remainder of a number n to m is A1, and B is the sum of each digit of N, there are: N % m = B % m = A1.
For example, for the sum of 151 and all of them 7, the remainder of 3 is 1.
2) If a number is a multiple of 3, the sum of the numbers is a multiple of 3.
For example, let's consider 8760, which is a multiple of 3, because the total number is 8 + 7 + 6 + 0 = 21, which is a multiple of 3.
Deduction: If a number is a multiple of 3, the number is arranged as a new number, and the number is still a multiple of 3.
Time Complexity:O (nlongn)
Source code:
Brute force code:
// Memory Time// 1347K 0MS// by : Snarl_jsb// 2014-09-10-09.28#include<algorithm>#include<cstdio>#include<cstring>#include<cstdlib>#include<iostream>#include<vector>#include<queue>#include<stack>#include<map>#include<string>#include<climits>#include<cmath>#define N 100#define MAXN 100#define LL long longusing namespace std;long long n,summ;long long a[N];bool cmp(LL a,LL b){ return a>b;}LL ans[N];LL idx;LL Max;void work(int* b,int n){LL sum1=0;for(int i=0;i<n;i++) { sum1+=a[b[i]]; } if(sum1%3==0&&sum1>Max) { Max=sum1; idx=n; for(int i=0;i<n;i++) { ans[i]=a[b[i]]; } }}void _gen_comb(int* a,int s,int e,int m,int& cnt,int* temp){int i;if (!m)work(temp,cnt);elsefor (i=s;i<=e-m+1;i++){temp[cnt++]=a[i];_gen_comb(a,i+1,e,m-1,cnt,temp);cnt--;}}void gen_comb(int n,int m){int a[MAXN],temp[MAXN],cnt=0,i;for (i=0;i<n;i++)a[i]=i+1;_gen_comb(a,0,n-1,m,cnt,temp);}int main(){// freopen("C:\\Users\\ASUS\\Desktop\\cin.cpp","r",stdin);// freopen("C:\\Users\\ASUS\\Desktop\\cout.cpp","w",stdout); while(~scanf("%I64d",&n)) { LL sum=0; for(int i=1;i<=n;++i) { scanf("%I64d",a+i); sum+=a[i]; } summ=sum;// cout<<sum<<endl; sort(a+1,a+1+n,cmp); if(!(sum%3)) { for(int i=1;i<=n;i++) { printf("%I64d",a[i]); } puts(""); continue; } bool flag=0; for(int i=n;i>1;--i) { sum-=a[n]; if(!(sum%3)) { for(int j=1;j<i;j++) printf("%I64d",a[j]); puts(""); flag=1; break; } } if(flag) continue; Max=LONG_LONG_MIN; for(int i=n;i>=1;--i) { gen_comb(n,i); } if(sizeof(ans)==0) { puts("impossible\n"); continue; } sort(ans,ans+idx,cmp); for(int i=0;i<idx;++i) { printf("%I64d",ans[i]); } puts(""); } return 0;}
Mathematical Methods:
// Memory Time// 1347K 0MS// by : Snarl_jsb// 2014-09-10-11.37#include<algorithm>#include<cstdio>#include<cstring>#include<cstdlib>#include<iostream>#include<vector>#include<queue>#include<stack>#include<map>#include<string>#include<climits>#include<cmath>#define N 10000#define LL long longusing namespace std;LL n;LL a[N];LL ans[N];LL n1,n2,n3;LL q1[N],q2[N],q3[N];bool cmp(LL a,LL b){ return a>b;}int main(){// freopen("C:\\Users\\ASUS\\Desktop\\cin.cpp","r",stdin);// freopen("C:\\Users\\ASUS\\Desktop\\cout.cpp","w",stdout); while(scanf("%d",&n)!=EOF) { n1=n2=n3=0; LL sum=0; for(LL i=1;i<=n;i++) { scanf("%d",&a[i]); sum+=a[i]; if(a[i]%3==0) { q1[++n1]=a[i]; } else if(a[i]%3==1) q2[++n2]=a[i]; else q3[++n3]=a[i]; } if(sum%3==0) { sort(a+1,a+1+n); for(int i=n;i>=1;--i) { printf("%d",a[i]); } puts(""); continue; } sort(q1+1,q1+1+n1,cmp); sort(q2+1,q2+1+n2,cmp); sort(q3+1,q3+1+n3,cmp); if(sum%3==1) { if(n2>=1) { n2--; } else if(n3>=2) { n3-=2; } else { puts("impossible\n"); continue; } } else if(sum%3==2) { if(n1>=2) { n1-=2; } else if(n2>=1) { n2--; } else { puts("impossible\n"); continue; } } LL idx=0; for(int i=1;i<=n1;++i) { ans[++idx]=q1[i]; } for(int i=1;i<=n2;++i) { ans[++idx]=q2[i]; } for(int i=1;i<=n3;++i) { ans[++idx]=q3[i]; } sort(ans+1,ans+1+idx,cmp); for(int i=1;i<=idx;i++) { printf("%I64d",ans[i]); } puts(""); } return 0;}
Number Theory-division-returns the maximum multiple of 3 in an integer set.