暑假day1

4 篇文章 0 订阅

题目名称

素数

晨练

奇怪的桌子

学校

存盘文件名

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个用空格隔开的整数:nm

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;
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值