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

posted @ 2010-11-03 16:06  Sephiroth.L.  阅读(1041)  评论(0编辑  收藏  举报