Noip 2002 普及组 复赛试题

The First:

级数求和                                 

【P1035】级数求和

解题报告:

  double运算即可, 注意细节.

#include <iostream>

using namespace std;

int main()
{
    int k;
    double n = 0, Sn = 0;
    cin >> k;
    while(Sn<=k)
    {  
        ++n;
        Sn = 1 / n + Sn;
    }
    cout << n;
    return 0;
}
级数求和

 

 

The Second:

选数

【P1036】选数

解题报告:

  将给出的数据做升序全排列(回溯), 将得出的数据judge, 若是素数, 总数 + 1。

  若用全排列而不用升序全排列会有重复。

#include <iostream>
#include <math.h>

using namespace std;

int n, k, a[21], b[21] = {0}, c[21], tot = 0, aox = 0;

void judge(int tot)
{
    int k = 2;
    while(k <= sqrt(tot) && tot % k != 0) k++;
    if(k > sqrt(tot)) aox++;
}

int search(int l)
{
    int i;
    for(i = 1; i <= n; i++)
    {
        if(b[i] == 0 && (c[l - 1] < i))
        {
            tot = a[i] + tot;
            c[l] = i;
            b[i] = 1;
            if(l == k) judge(tot);
              else search(l + 1);
            b[i] = 0;
            tot = tot - a[i];
        }
    }
}

int main()
{
    int i;
    cin >> n >> k;
    for(i = 1; i <= n; i++) cin >> a[i];
    search(1);
    cout << aox;
    return 0;
} 
选数

 

 

The Third:

产生数

[P1037]产生数

解题报告:

  DFS求出每个数字可以变换的次数, 乘法原理相乘。

  因为每个数字最多可以变成8种数字, 所以可以使用高精乘低精。

#include <iostream>
#include <string>
#include <cstring>

using namespace std;

int change[16][2], sum[10], tot = 0, judge[10], k;
int a[1001], len = 0;

int Mul(int l)
{
    int x = 0;
    for(int i = 0; i <= len; ++i)
    {
        a[i] = a[i] * l + x;
        x = a[i] / 10;
        a[i] = a[i] % 10;
    }
    if(x != 0) a[++len] = x;
}

int DFS(int l)
{
    for(int i = 1; i <= k; ++i)
    {
        if(change[i][0] == l && judge[change[i][1]] == 0)
        {
            tot++;
            judge[change[i][1]] = 1;
            DFS(change[i][1]);
        }
    }
}

int main()
{
    string n;
    cin >> n >> k;
    for(int i = 1; i <= k; ++i)
        cin >> change[i][0] >> change[i][1];
    for(int i = 0; i <= 9; ++i)
    {
        judge[i] = 1;
        DFS(i);
        sum[i] = tot + 1;
        tot = 0;
        memset(judge, 0, sizeof(judge));
    }
    a[0] = sum[n[0] - 48];
    for(int i = 1; i < n.length(); ++i)
        Mul(sum[n[i] - 48]);
    for(int i = len; i >= 0; --i) cout << a[i];
    return 0;
}
产生数

 

The Fourth:

过河卒

[P1002]过河卒

 解题报告:

  将马和马能跳到的位置标记成1, 然后dp[i][j] = dp[i - 1][j] + dp[i][j - 1];

#include <iostream>

using namespace std;

long long b[30][30];
int a[30][30];

int main()
{
    int x, y, n, m;
    cin >> x >> y >> n >> m;
    x = x + 2; y = y + 2; n = n + 2; m = m + 2;
    a[n][m] = 1;
    a[n + 1][m + 2] = 1;
    a[n + 1][m - 2] = 1;
    a[n + 2][m - 1] = 1;
    a[n + 2][m + 1] = 1;
    a[n - 1][m + 2] = 1;
    a[n - 1][m - 2] = 1;
    a[n - 2][m + 1] = 1;
    a[n - 2][m - 1] = 1;
    for(int i = 2; i <= x; ++i)
        for(int j = 2; j <= y; ++j)
        {
            b[2][2] = 1;
            if(a[i][j] != 1) b[i][j] = b[i - 1][j] + b[i][j - 1];
        }
    cout << b[x][y];
    return 0;
}
过河卒

The End..

转载于:https://www.cnblogs.com/without-sugar/p/5844738.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值