Codeforces Round #131 (Div. 2)214B Hometask(想法题)
题目链接: 传送门
Hometask
Time Limit: 2 seconds Memory Limit: 256 megabytes
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 by 2, 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 contains n 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 11 3 4 5 4 5 3 5 3 4 4 0 8 3 2 5 1 5 2 2 3
Sample Output
0 5554443330 -1
思路:
题目大意:给一个都是数字的集合,组成一个尽量大的数使之能被2,3,5整除。
找出集合中是否有9,没有则停止判断。对于给出的数字集合,看总和是否能被3整除,能直接从大到小输出,不行的话,对3取模,对取模结果(1或2)单独判断,删除集合中某些数字是否能被3整除,不行则停止。输出是忽略前导0。(训练赛时在对模结果为1的特判中折腾了好久。模结果为1,则可以删去集合中一个对3取模也为1的数,或是删去两个对3取模为2的数,模结果为2同理。 官方题解
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; typedef __int64 LL; struct Node { LL cnt,val; bool flag; Node():cnt(0),val(0),flag(false) {} }; bool cmp(Node x,Node y) { return x.val > y.val; } int main() { LL N,tmp,maxx = 0,sum = 0; bool Isz = false; Node num[15]; scanf("%I64d",&N); for (int i = 0; i < N; i++) { scanf("%I64d",&tmp); sum += tmp; num[tmp].val = tmp; num[tmp].cnt++; num[tmp].flag = true; if (tmp > maxx) { maxx = tmp; } if (tmp == 0) { Isz = true; } } if (!Isz) { printf("-1\n"); } else { if (sum % 3 == 0) { if (num[maxx].val == 0) { printf("0\n"); } else { for (int i = maxx; i >= 0; i--) { if(num[i].flag) { while (num[i].cnt--) { printf("%I64d",num[i].val); } } } printf("\n"); } } else { LL r = sum % 3; bool Can = false; LL cnt = 0; if (r == 1) { for (int i = 1; i <= maxx ; i+=3) { if (num[i].flag && num[i].cnt) { Can = true; num[i].cnt--; if (num[i].cnt == 0) { num[i].flag = false; num[i].val = 0; } break; } } if(!Can) { for (int i = 2;i <= maxx;i+=3) { if (num[i].flag && num[i].cnt) { while (num[i].cnt--) { cnt++; if (num[i].cnt == 0) { num[i].flag = false; } if (cnt == 2 || num[i].cnt == 0) { if (cnt == 2) { Can = true; } break; } } if (cnt == 2) { Can = true; break; } } } } } else if (r == 2) { for (int i = 2; i <= maxx; i+=3) { if (num[i].flag && num[i].cnt) { Can = true; num[i].cnt--; if(num[i].cnt == 0) { num[i].flag = false; num[i].val = 0; } break; } } if (!Can) { for (int i = 1; i <= maxx; i+=3) { if (num[i].flag && num[i].cnt) { while (num[i].cnt--) { cnt++; if (num[i].cnt == 0) { num[i].flag = false; } if (cnt == 2 || num[i].cnt == 0) { if (cnt == 2) { Can = true; } break; } } } if (cnt == 2) { Can = true; break; } } } } if (!Can) { printf("-1\n"); } else { bool Noz = false; for (int i = 0;i <= maxx;i++) { if (num[i].flag && num[i].val) { Noz = true; break; } } if (Noz) { for (int i = maxx;i >= 0;i--) { if (num[i].flag && num[i].cnt) { while (num[i].cnt--) { printf("%I64d",num[i].val); } } } printf("\n"); } else { printf("0\n"); } } } } return 0; }
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int main() { int N; while (~scanf("%d",&N)) { int ans[10] = {0}; int tmp,sum = 0; bool flag = false; for (int i = 0;i < N;i++) { scanf("%d",&tmp); ans[tmp]++; sum += tmp; } if (ans[0] == 0) { printf("-1\n"); } else { flag = true; if (sum % 3 == 1) { if (ans[1] + ans[4] + ans[7]) { for (int i = 1;i <= 7;i += 3) { if (ans[i]) { ans[i]--; break; } } } else if (ans[2] + ans[5] + ans[8] >= 2) { for (int i = 2,j = 1;i <= 8;i+=3) { while (ans[i] && j <= 2) { ans[i]--; j++; } } } } else if (sum % 3 == 2) { if (ans[2] + ans[5] + ans[8]) { for (int i = 2;i <= 8;i += 3) { if (ans[i]) { ans[i]--; break; } } } else if (ans[1] + ans[4] + ans[7] >= 2) { for (int i = 1,j = 1;i <= 7;i += 3) { while (ans[i] && j <= 2) { ans[i]--; j++; } } } } } if (flag) { if (ans[1] + ans[2] + ans[3] + ans[4] + ans[5] + ans[6] + ans[7] + ans[8] + ans[9]) { for (int i = 9;i >= 0;i--) { while (ans[i]--) { printf("%d",i); } } } else { printf("0"); } printf("\n"); } } return 0; }
后来参考了别人代码= =果然自己太native,运用一点数学思想可以省略很多特判= =还是要注重多思考啊。
- Linux--管道pipe
- Mybatis的ResultMap的使用(转)
- 自增锁ID复用问题
- Codeforces Round #131 (Div. 2)214B Hometask(想法题)
- php hash函数
- 大数相加+斐波那契数列
- git快速入门(一)git环境配置
- 转 android 侧滑实现
- AJAX 注意事项
- 347. Top K Frequent Elements
- log4j:WARN No appenders could be found for logger报错问题解决方案
- uvalive 6888 Ricochet Robots bfs
- java向上转型和向下转型
- Socket异步通信学习二
- Linux常用指令 2
- python学习例程2-获取用户输入
- ffmpeg AVPacket & AVFrame
- 012——hibernate之集合映射
- [hihoCoder太阁最新面经算法竞赛8]B.Dice Possibility
- BroadcastReceiver静态和动态注册简单Demo