【t005】数字构造问题
来源:互联网 发布:mac版qq与win版啥区别 编辑:程序博客网 时间:2024/05/11 15:59
Time Limit: 1 second
Memory Limit: 50 MB
【问题描述】
给定一个只包含数字[0..9]的字符串,请使用字符串中的某些字符,构建一个能够整除15最大的整数。注意,字符串中的每个字符只能使用一次。 任务:求由给定字符串构造的能够整除15的最大整数
【输入】
共1行;输入数据为一个只包含数字[0..9]字符串,字符串的长度为1..1000。如果无法构建出该数字,请输出“impossible”。
【输出】
输出一行数字串,表示能够整除15的最大整数。
【输入样例】
02041
【输出样例1】
4200
【题目链接】:http://noi.qz5z.com/viewtask.asp?id=t005
【题解】
/* 一个数字能被15整除; 则这个数的各个位上的数字的和是3的倍数; 末尾数字是0或5. 把所有的数字从大到小排序; 所有数字的和模3的结果; 1.如果为0 如果数字里面有0,则排序后0在最后面,则直接输出; 如果数字里面没有0,但是有5,则把1个5放在最后面;然后输出; else put("Impossible"); 2.如果为1 则如果有余数为1的数字,选那个最小的,删掉它; 如果没有余数为1的数字,找两个余数为2的数字; { 如果有0,则直接找两个最小的,删掉 如果没有0,则要考虑 是不是减掉一个5之后,还能找到两个余数为2的数字; 能则删掉; } 是否删掉了数字使得所有数字的和%3==0? 是则根据有没有5和0,输出相应的答案; 否则无解; 2.如果为2 则如果有1个余数为2的数字; { 如果有0,则直接找最小的那个删掉; 如果没有0,则要考虑 是不是减掉一个5之后,还能找到一个余数为2的数字; 能则删掉那个数字,否则"去找两个余数为1的数字",删掉; } 没有 则去找两个余数为1的数字; 如果有就删掉最小的两个; 是否删掉了数字使得所有数字的和%3==0? 是则根据有没有5和0,输出相应的答案; 否则无解;*/
【完整代码】
#include <cstdio>#include <string>#include <iostream>#include <algorithm>using namespace std;const int MAXN = 1000+100;string s;int bo[3];int a[MAXN],n,num = 0,t5 = 0,t0 = 0;bool ok1;bool cmp(int x,int y){ return x > y;}void find5(){ for (int i = 1;i <= n;i++) if (a[i]==5) { a[i]=-1; a[n+1] = 5; break; }}void output(){ int l = 1,r = n+1; while (a[l]==0 || a[l]==-1) l++; if (l>r) puts("0"); for (int i = l;i <= n+1;i++) if (a[i]!=-1) printf("%d",a[i]);}void pd(){ if (ok1)//如果删掉数了 { if (t0)//有0就直接输出 { output(); exit(0); } if (t5)//执行这一段就表示没0,则如果有5就把5移到最后输出 { find5(); output(); exit(0); } } //没完成删数或没有0和5就输出无解 puts("impossible");}int main(){ //freopen("F:\\rush.txt","r",stdin); cin >> s; n = s.size(); for (int i = 0;i <= n-1;i++) { a[i+1] = s[i]-'0'; bo[a[i+1]%3]++; num+=a[i+1]; if (a[i+1]==5) t5++; if (a[i+1]==0) t0++; } sort(a+1,a+1+n,cmp); a[n+1] = -1; int x = num%3; if (x==0) { if (t0) { for (int i = 1;i <= n;i++) printf("%d",a[i]); return 0; } if (t5) { find5(); for (int i = 1;i <= n+1;i++) if (a[i]!=-1) printf("%d",a[i]); return 0; } puts("impossible"); return 0; } if (x==1) { ok1 = false; if (bo[1]) { for (int i = n;i >= 1;i--) if (a[i]%3==1) { a[i] = -1; break; } ok1 = true; } if (!ok1 && bo[2]>=2) { if (t0>0)//直接找两个余数为2的删掉(最小) { int cnt = 0; for (int i = n;i >= 1;i--) if (a[i]%3==2) { cnt++; a[i] = -1; if (cnt==2) break; } ok1 = true; } //如果没有0,则还需要一个5 //看一下删掉一个5(所以你得先有一个5) //之后还有没有两个余数为2的)->所以bo[2]>=3是条件 if (!ok1 && t5 && bo[2]>=3) { //如果5只有一个,就不能选5 bool ban5 = false; int cnt = 0; if (t5==1) ban5 = true; for (int i = n;i>=1;i--) if (a[i]%3==2) { if (ban5) if (a[i]==5) continue; a[i] = -1; cnt++; if (cnt==2) break; } ok1 = true; } } //删数完成,根据0和5的个数判断输出 pd(); } if (x==2) { ok1 = false; if (bo[2]) { if (t0) { for (int i = n;i>=1;i--) if (a[i]%3==2) { a[i] = -1; break; } ok1 = true; } //如果下面这段执行是肯定没有0了 //则肯定要有一个5,减去5会让bo[2]--,所以bo[2]要大于1 if (!ok1 && t5 && bo[2]>1) { bool ban5 = false; if (t5==1) ban5 = true; for (int i = n;i >= 1;i--) if (a[i]%3==2) { if (ban5) if (a[i]==5) continue; a[i] = -1; break; } ok1 = true; } } if (!ok1 && bo[1]>=2) { int cnt = 0; for (int i = n;i >= 1;i--) if (a[i]%3==1) { a[i] = -1; cnt++; if (cnt==2) break; } ok1 = true; } pd(); } return 0;}
0 0
- 【t005】数字构造问题
- 【t030】数字构造
- CONNECT BY 构造连续数字
- 数字问题
- 数字问题
- 构造100以内的英文数字
- Leetcode 179 Largest Number 构造最大数字
- 构造函数问题
- 构造函数的问题
- 构造函数的问题
- 构造函数初始化问题
- java 构造函数问题
- C++ 构造函数问题
- C++对象构造问题
- Servlet 构造函数问题
- 复制构造函数问题
- java中的构造问题
- C++构造函数调用构造函数问题
- window双系统同切换
- Android studio中使用jdk1.8
- Leetcode 66. Plus One
- android studio 一键清除无用资源
- 洛谷 1086——花生采摘(交叉模拟)
- 【t005】数字构造问题
- HDU1203 I NEED A OFFER! (0-1背包)
- 【初码干货】关于.NET玩爬虫这些事
- git进行远程代码仓库管理(二)
- Python绝技笔记--------python利用dpkt操作pcap
- super 学习笔记
- 电信诈骗之更改号码显示
- 【密码学】一万字带您走进密码学的世界(下)
- BZOJ 4247(挂饰-背包)