首先是Self Numbers,题意是找出10000以内所有不能有其他数+他们每个位数上的数字和。。。做法就是打表,挺简单的我一开始直接无脑写个程序暴力求10000以内所有符合的数,扔到一个数组里直接输出,美汁汁
代码如下:
#include<cstdio>
using namespace std;
int vis[10100];
void ret(int t) {
int temp = t;
while (t>0) {
temp += t % 10;
t /= 10;
}
vis[temp] = 1;
}
int main() {
for (int i = 1; i <= 10000; i++) {
ret(i);
}
for (int i = 1; i <= 10000; i++) {
if (!vis[i]) {
printf("%d\n", i);
}
}
}
然后是Humble Numbers
题意:找出前5842个质因数只有2,3,5,7的数翻译过来就是了,凑字数
方法·:既然质因子都是2,3,5,7,那么得到的数乘以2,3,5,7也一定符合,假定已有n个确定的数,那么我们就把这n个数都乘以2,3,5,7,得到的未找的且最小的数就是第n+1个符合的数, 但显然不可能所有找到的数都乘以2,3,5,7,所以我们就要有四个标记,分别表示乘以2,3,5,7,剩下的emm,我组织了下语言发现怎么都怪怪的吃了语文的亏,就直接看状态转移方程吧,看一下也差不多能懂 dp[i] = min(min(dp[top2] * 2, dp[top3] * 3), min(dp[top5] * 5, dp[top7] * 7));
同时保证有dp[topn] * n <= dp[i]
终于度过了难熬的描述阶段,上代码
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
int dp[6000];
void init() {
dp[1]=1;
int top2, top3, top5, top7;
top2 = top3 = top5 = top7 = 1;
for (int i = 2; i <= 5842; i++) {
dp[i] = min(min(dp[top2] * 2, dp[top3] * 3), min(dp[top5] * 5, dp[top7] * 7));
while (dp[top2] * 2 <= dp[i]) top2++;//维护dp[topn] * n <= dp[i]
while (dp[top3] * 3 <= dp[i]) top3++;
while (dp[top5] * 5 <= dp[i]) top5++;
while (dp[top7] * 7 <= dp[i]) top7++;
}
}
int main() {
ios::sync_with_stdio(false);
int n;
init();
while (cin>>n&& n) {
if (n == 0) break;
int t = n % 10;
int a = n % 100;
if (t == 1 && a != 11) {//脑袋抽筋了可能,竟然用cout输出,比printf麻烦多了,还不号直接复制输出格式,然后少加了".",然后WA了一次233
cout << "The " << n << "st humble number is " << dp[n] << "." << endl;
}
else if (t == 2 && a != 12) {
cout << "The " << n << "nd humble number is " << dp[n] << "." << endl;
}
else if (t == 3 && a != 13) {
cout << "The " << n << "rd humble number is " << dp[n] << "." << endl;
}
else {
cout << "The " << n << "th humble number is " << dp[n] << "." << endl;
}
}
}
//愉快结束