首页 > 代码库 > Codeforce 214 Div 2 B.Hometask
Codeforce 214 Div 2 B.Hometask
题目描述:
Description
Furik loves math lessons very much, so he doesn‘t attend them, unlike Rubik. But now Furik wants to get a good mark for math. For that Ms. Ivanova, his math teacher, gave him a new task. Furik solved the task immediately. Can you?
You are given a set of digits, your task is to find the maximum integer that you can make from these digits. The made number must be divisible by2, 3, 5 without a residue. It is permitted to use not all digits from the set, it is forbidden to use leading zeroes.
Each digit is allowed to occur in the number the same number of times it occurs in the set.
Input
A single line contains a single integer n(1?≤?n?≤?100000) — the number of digits in the set. The second line containsn digits, the digits are separated by a single space.
Output
On a single line print the answer to the problem. If such number does not exist, then you should print -1.
Sample Input
1 0
0
11 3 4 5 4 5 3 5 3 4 4 0
5554443330
8 3 2 5 1 5 2 2 3
-1
就是给你n个数,让你求由这n个数组成的,能被2,3,5整除的的最大的数。
思路:
这道题本来是用来练手速的,没想到一做就是一个下午。最后还是看了BMan的代码才勉强AC的,不过看了BMan的代码之后,真的学到了很多的东西!例如,学到了CF里面有一个ONLINE_JUDGE的宏变量,可以利用条件编译来方便测设与提交!最重要的是学到了一个思路,那就是预处理的优美之处!
具体做法是:因为答案要能被3整除,所以各位数之和必须为3的倍数!如果是,直接输出;否则的话有两种可能:
1. sum % 3 == 1 这种情况只需在数列中找到一个num[i] % 3 == 1 的数去掉就可以咯,如果没有就找两个num[] % 3 == 2 去掉就可以了!
2..sum % 3 == 2,这种情况跟上一种是基本一致的,就不在赘述了!
这个题目有一个易错点,就是在判断前导0,BMan给出了一个很强大的做法,具体的做法请看代码实现:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <string> #include <algorithm> #include <vector> #define N 1000010 using namespace std; void debug() { #ifdef ONLINE_JUDGE #else freopen( "in.txt", "r", stdin ); #endif // JUDGE_ONLINE } int main() { debug(); //freopen( "in.txt", "r", stdin ); int n; while( scanf( "%d", &n ) != EOF ) { int num[N] = {0}; int vis[N]; int sum = 0; memset( vis, 0, sizeof( vis ) ); for( int i = 0; i < n; i++ ) { scanf( "%d", &num[i] ); sum += num[i]; } sort( num, num + n, greater<int>() ); if( sum % 3 == 1 ) { for( int i = n-1; i >= 0; i-- ) { if( num[i] % 3 == 1 ) { vis[i] = 1; sum -= num[i]; break; } } int two = 0; if( sum % 3 == 1 )//说明找不到num[i] % 3 == 1 的num { for( int i = n-1; i >= 0; i-- ) { if( num[i] % 3 == 2 ) { vis[i] = 1; if( ++two >= 2 ) { break; } } } if( two != 2 ) { printf( "-1\n" ); continue; } } } if( sum % 3 == 2 ) { for( int i = n-1; i >= 0; i-- ) { if( num[i] % 3 == 2 ) { vis[i] = 1; sum -= num[i]; break; } } int one = 0; if( sum % 3 == 2 ) { for( int i = n-1; i >= 0; i-- ) { if( num[i] % 3 == 1 ) { vis[i] = 1; if( ++one >= 2 ) { break; } } } if( one != 2 ) { printf( "-1\n" ); continue; } } } int cnt = 0; for( int i = 0; i < n; i++ ) { if( !vis[i] ) { num[cnt++] = num[i]; } } n = cnt; if( n == 0 || num[n-1] != 0 ) { printf( "-1" ); } else { int i = 0; while( i < n - 1 && num[i] == 0 )//判断前导0,如果一开始num[0]就等于0的话,由于已经进行了降序的排序,所以后面一定是0,这样的话与后面的代码结合就能够保证 //前导0的只输出一个0 { i++; } for( ; i < n; i++ ) { printf( "%d", num[i] ); } } putchar( 10 ); } return 0; }
通过今天的学习,我发现学习大神们的代码对提升自己的编码能力是有着很大的帮助的!要多看别人的代码!!!
One Day One Step!