NOIP2002普及组
第一题 阶级求和
【题目描述】
已知:Sn= 1+1/2+1/3+…+1/n。显然对于任意一个整数K,当n足够大的时候,Sn大于K。
现给出一个整数K(1<=k<=15),要求计算出一个最小的n;使得Sn>K。
【输入格式】
输入K。
【输出格式】
一个数N。
【样例输入】
1
【样例输出】
2
【分析】
记得考虑C++中“/”可以整除也可以实数除。
第二题 选数
【题目描述】
已知 n 个整数 x1,x2,…,xn,以及一个整数 k(k<n)。从 n 个整数中任选 k 个整数相加,可分别得到一系列的和。例如当 n=4,k=3,4 个整数分别为 3,7,12,19 时,可得全部的组合与它们的和为:
3+7+12=22 3+7+19=29 7+12+19=38 3+12+19=34。
现在,要求你计算出和为素数共有多少种。
例如上例,只有一种的和为素数:3+7+19=29)。
【输入格式】
输入格式:
n , k (1<=n<=20,k<n)
x1,x2,…,xn (1<=xi<=5000000
【输出格式】
一个整数(满足条件的种数)。
【样例输入】
4 3
3 7 12 19
【样例输出】
1
【分析】
递归求组合数,然后判断素数。
第三题 产生数
【题目描述】
给出一个整数 n(n<10^30) 和 k 个变换规则(k<=15)。
规则:一位数可变换成另一个一位数:规则的右部不能为零。
例如:n=234。有规则(k=2):
2-> 5
3-> 6
上面的整数 234 经过变换后可能产生出的整数为(包括原数):
234
534
264
564
共 4 种不同的产生数
给出一个整数 n 和 k 个规则。
求出:
经过任意次的变换(0次或多次),能产生出多少个不同整数。
仅要求输出个数。
【输入格式】
第一行n和k。
下面K行每行两个整数,表示转换规则
【输出格式】
一个整数(满足条件的个数)
【样例输入】
234 2
2 5
3 6
【样例输出】
4
【分析】
深搜每个数可以改变的个数,然后乘法原理。
第四题 马拦过河卒
【题目描述】
棋盘上A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。
棋盘用坐标表示,A点(0, 0)、B点(n, m)(n, m为不超过20的整数),同样马的位置坐标是需要给出的。现在要求你计算出卒从A点能够到达B点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。
【输入格式】
一行四个数据,分别表示B点坐标和马的坐标。
【输出格式】
一个数据,表示所有的路径条数。
【样例输入】
6 6 3 3
【样例输出】
6
【分析】
递推。
代码
第一题
#include <stdio.h>
int k;
double tem,n;
int main() {
scanf("%d%d",&k);
while (tem <= k) {
++n;
tem += 1 / n;
}
printf("%.0lf\n",n);
return 0;
}
第二题
#include <stdio.h>
#include <math.h>
#define MAXN 30
int a[MAXN],b[MAXN];
int ans,n,k;
bool check(int x) {
if (x < 2)
return 0;
for (int i = 2;i <= sqrt(x);++i)
if (x % i == 0)
return 0;
return 1;
}
void find(int x) {
if (x > k) {
int tem = 0;
for (int i = 1;i <= k;++i)
tem += a[b[i]];
if (check(tem))
++ans;
return;
}
for (int i = b[x - 1] + 1;i <= n - k + x;++i) {
b[x] = i;
find(x + 1);
}
}
int main() {
scanf("%d%d",&n,&k);
for (int i = 1;i <= n;++i)
scanf("%d",&a[i]);
find(1);
printf("%d\n",ans);
return 0;
}
第三题
#include <stdio.h>
#include <string.h>
#define MAXN 40
bool can[10][10];
bool v[10];
char s[MAXN];
int ans[30];
long long len,k,tem,x,y;
void find(int x) {
if (v[x])
return;
++tem;
v[x] = 1;
for (int i = 0;i < 10;++i)
if (can[x][i])
find(i);
}
void cheng(int t) {
int x = 0;
for (int i = 1;i <= ans[0];++i) {
ans[i] *= t;
ans[i] += x;
x = ans[i] / 10;
ans[i] %= 10;
}
if (x)
ans[++ans[0]] = x;
}
int main() {
ans[0] = ans[1] = 1;
scanf("%s%lld",s,&k);
if (!k)
ans[1] = 0;
else {
for (int i = 0;i < k;++i) {
scanf("%lld%lld",&x,&y);
can[x][y] = 1;
}
len = strlen(s);
for (int i = 0;i < len;++i) {
memset(v,0,sizeof(v));
tem = 0;
find(s[i] - '0');
cheng(tem);
}
}
for (int i = ans[0];i > 0;--i)
printf("%d",ans[i]);
return 0;
}
第四题
#include <stdio.h>
#define MAXN 30
int f[MAXN][MAXN];
int x,y,n,m;
int xx[8] = {-2,-1,1,2,2,1,-1,-2};
int yy[8] = {1,2,2,1,-1,-2,-2,-1};
bool inmap(int x,int y) {
return (x >= 0) && (x <= n) && (y >= 0) && (y <= m);
}
int main() {
scanf("%d%d%d%d",&n,&m,&x,&y);
f[x][y] = -1;
for (int i = 0;i < 8;++i) {
int tx = x + xx[i],ty = y + yy[i];
if (inmap(tx,ty))
f[tx][ty] = -1;
}
if (f[0][0] != -1)
f[0][0] = 1;
for (int i = 1;i <= m;++i)
if ((f[0][i] != -1) && (f[0][i - 1] != -1))
f[0][i] = f[0][i - 1];
for (int i = 1;i <= n;++i) {
if ((f[i][0] != -1) && (f[i - 1][0] != -1))
f[i][0] = f[i - 1][0];
for (int j = 1;j <= m;++j)
if (f[i][j] != -1) {
if (f[i - 1][j] != -1)
f[i][j] += f[i - 1][j];
if (f[i][j - 1] != -1)
f[i][j] += f[i][j - 1];
}
}
if (f[n][m] == -1)
f[n][m] = 0;
printf("%d\n",f[n][m]);
return 0;
}
(Sephiroth Lee原创,转载请注明出处。http://www.cnblogs.com/sephirothlee/archive/2010/11/03/1868167.html)
浙公网安备 33010602011771号