题目名称 | 素数 | 晨练 | 奇怪的桌子 | 学校 |
存盘文件名 | sum.pas/c/cpp | run.pas/c/cpp | table.pas/c/cpp | school.pas/c/cpp |
输入文件名 | sum.in | run.in | table.in | school.in |
输出文件名 | sum.out | run.out | table.out | school.out |
时限 | 1s | 1s | 3s | 1s |
内存限制 | 256M | 256M | 256M | 256M |
【注意事项】:请自行完成题目,切勿讨论。
素数
【问题描述】
有一些正整数能够表示为一个或连续多个素数的和。那么给定一些正整数,求有多少种这样的表示。
【输入格式】
若干行,每行一个正整数(<=32767),输入一个0结束。
【输出格式】
对于输入的每一个正整数,输出一行一个数,表示其表示方法的个数。
【输入样例】
2
3
17
41
20
666
12
53
0
【输出样例】
1
1
2
3
0
0
1
2
【数据范围与约定】
对于100%的数据,所有数<=32767。
素数的一些性质:
2是唯一的既是有偶数,又是质数的数。
偶数+偶数=偶数
偶数+奇数=奇数
奇数+奇数=偶数
由以上可知,
两个相同的数相加不可能为素数。
并且一个奇数加上一个奇数为偶数也不可能为素数。
但题给条件说要连续的素数。
所以以上结论
是多虑了。
仔细审题!!!!
于是可以直接枚举素数累加就行了。
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=32767;
int totP = 0,tot = 0;
int a[100010],Prime[maxn+10],ans[100010];
bool Mark[maxn+10];
int main(){
freopen("sum.in","r",stdin);
freopen("sum.out","w",stdout);
memset(Mark,true,sizeof(Mark));
Mark[0] = Mark[1] = false;
tot = 0;
while(1){
tot++;
scanf("%d",&a[tot]);
if(a[tot] == 0){
tot--;
break;
}
}
for(int i = 2; i <= maxn; i++){
for(int j = 2; i*j<=maxn; j++) if(Mark[i*j]) Mark[i*j] = false;
}
for(int i = 2; i <= maxn; i++){
if(Mark[i]) Prime[++totP] = i;
}
for(int i = 1; i<= totP; i++){
int Sum = 0;
for(int j = i; j<=totP; j++){
Sum+=Prime[j];
if(Sum > maxn) break;
ans[Sum]++;
}
}
for(int i = 1; i<= tot; i++){
printf("%d\n",ans[a[i]]);
}
return 0;
}
晨练
【问题描述】
小 Y 打算通过锻炼来培养自己的运动细胞,他选择的运动方式是每天进行N分钟的晨跑(1<=N<=10000)。
在每分钟的开始,小 Y 会选择下一分钟是用来跑步还是休息。小Y 的体力限制了他跑步的距离。更具体地,如果小Y 选择在第i 分钟内跑步,他可以在这一分钟内跑D_i(1<=D_i<=1000)米,并且他的疲劳度会增加1。不过,无论何时小Y 的疲劳度都不能超过M(1 <=M<=500)。如果小Y 选择休息,那么他的疲劳度就会每分钟减少1,但他必须休息到疲劳度恢复到0为止。在疲劳度为0 时休息的话,疲劳度不会再变动。晨跑开始时,小Y 的疲劳度为0。还有,在N分钟的锻炼结束时,小Y 的疲劳度也必须恢复到0,否则他将没有足够的精力来对付这一整天中剩下的事情。 请你计算一下,小 Y 最多能跑多少米。
【输入格式】
第1行:2个用空格隔开的整数:n,m。
第2..n+1行:第i+1行为1个整数D_i。
【输出格式】
输出一行为一个整数,表示在满足所有限制条件的情况下,小y能跑的最大距离。
【输入样例】
5 2
5
3
4
2
10
【输出样例】
9
【数据范围与约定】
对于30%的数据:n<=50。
对于100%的数据:n<=10000。
这道题呢..
忽略了 f[i][0] = max(f[i-1][0],f[i][0])这个方程,导致状态没有转移了。。
同时答案应该在f[n+1][0]而不是f[n][0],毕竟在n的时候还是可以选择休息的。
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int maxn = 10000;
int n,m;
int d[maxn+10];
int f[maxn+10][510];
int main(){
freopen("run.in","r",stdin);
freopen("run.out","w",stdout);
scanf("%d %d",&n,&m);
for(int i = 1; i <= n; i++){
scanf("%d",&d[i]);
}
memset(f,0,sizeof(f));
for(int i = 1; i <= n+1; i++){
f[i][0] = max(f[i-1][0],f[i][0]);
for(int j = 1; j<= m; j++){
f[i][j] = max(f[i][j],f[i-1][j-1] + d[i-1]);
if(i >= j) f[i][0] = max(f[i][0],f[i-j][j]);
}
}
printf("%d",f[n+1][0]);
return 0;
}