历年NOIP水题泛做

Posted Ra1nbow

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了历年NOIP水题泛做相关的知识,希望对你有一定的参考价值。

快noip了就乱做一下历年的noip题目咯..


 

noip2014 飞扬的小鸟

其实这道题并不是很难,但是就有点难搞 听说男神错了一个小时..

就是$f_{i,j}$表示在第$i$个位置高度为$j$的时候最小点击次数

递推的话对于上升的情况只做一次,后面几次在后面再做..

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int Maxn = 10010;
const int Maxm = 1010;
const int inf = 1e9;
int f[2][Maxm];
int n, m, K;
int l[Maxn], u[Maxn]; bool p[Maxn];
int X[Maxn], Y[Maxn];
int _min ( int x, int y ){ return x < y ? x : y; }
int main (){
    int i, j, k;
    scanf ( "%d%d%d", &n, &m, &K );
    l[0] = 0; u[0] = m+1;
    for ( i = 1; i <= n; i ++ ){ scanf ( "%d%d", &X[i], &Y[i] ); l[i] = 0; u[i] = m+1; }
    for ( i = 1; i <= K; i ++ ){
        int x;
        scanf ( "%d", &x );
        p[x] = true;
        scanf ( "%d%d", &l[x], &u[x] );
    }
    int st = 0;
    for ( i = 0; i <= m; i ++ ) f[st][i] = 0;
    int num = 0;
    for ( i = 1; i <= n; i ++ ){
        st = st^1;
        for ( j = 0; j <= m; j ++ ) f[st][j] = inf;
        bool bk = false;
        for ( j = l[i-1]+1; j < u[i-1]; j ++ ){
            if ( f[st^1][j] == inf ) continue;
            bk = true;
            f[st][_min(j+X[i],m)] = _min ( f[st][_min(j+X[i],m)], f[st^1][j]+1 );
        }
        for ( j = 0; j <= m; j ++ ){
            if ( f[st][j] != inf ) f[st][_min(j+X[i],m)] = _min ( f[st][_min(j+X[i],m)], f[st][j]+1 );
        }
        for ( j = l[i-1]+1; j < u[i-1]; j ++ ){
            if ( f[st^1][j] == inf ) continue;
            if ( j-Y[i] > l[i] && j-Y[i] < u[i] ) f[st][j-Y[i]] = _min ( f[st][j-Y[i]], f[st^1][j] );
        }
        if ( bk == false ){ printf ( "0\n%d\n", num-1 ); return 0; }
        if ( p[i] == true ) num ++;
    }
    int ans = inf;
    for ( i = 1; i <= m; i ++ ) ans = _min ( ans, f[st][i] );
    printf ( "1\n%d\n", ans );
    return 0;
}

  


noip2013 货车运输

就是裸的最大瓶颈树..

通俗点说就是最大生成树再用st表维护一下路径最小值..

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int Maxn = 10010;
const int Maxm = 50010;
struct node {
    int y, next, d;
}a[Maxn*2]; int first[Maxn], len;
void ins ( int x, int y, int d ){
    len ++;
    a[len].y = y; a[len].d = d;
    a[len].next = first[x]; first[x] = len;
}
struct lnode {
    int x, y, d;
}list[Maxm];
bool cmp ( lnode x, lnode y ){ return x.d > y.d; }
int n, m, q;
int fa[Maxn]; bool fw[Maxn];
int ff ( int x ){
    if ( fa[x] == x ) return x;
    return fa[x] = ff (fa[x]);
}
int minn[Maxn][15], fat[Maxn][15], dep[Maxn];
int _min ( int x, int y ){ return x < y ? x : y; }
void dfs ( int x, int f ){
    fw[x] = true;
    for ( int i = 1; i <= 14; i ++ ){
        fat[x][i] = fat[fat[x][i-1]][i-1];
        minn[x][i] = _min ( minn[x][i-1], minn[fat[x][i-1]][i-1] );
    }
    for ( int k = first[x]; k; k = a[k].next ){
        int y = a[k].y;
        if ( y == f ) continue;
        fat[y][0] = x;
        minn[y][0] = a[k].d;
        dep[y] = dep[x]+1;
        dfs ( y, x );
    }
}
int lca ( int x, int y ){
    int ret = 0x7fffffff;
    if ( dep[x] < dep[y] ) swap ( x, y );
    for ( int i = 14; i >= 0; i -- ){
        if ( dep[fat[x][i]] >= dep[y] ){
            ret = _min ( ret, minn[x][i] );
            x = fat[x][i];
        }
    }
    if ( x == y ) return ret;
    for ( int i = 14; i >= 0; i -- ){
        if ( fat[x][i] != fat[y][i] ){
            ret = _min ( ret, minn[x][i] );
            ret = _min ( ret, minn[y][i] );
            x = fat[x][i]; y = fat[y][i];
        }
    }
    return _min ( ret, _min ( minn[x][0], minn[y][0] ) );
}
int main (){
    int i, j, k;
    scanf ( "%d%d", &n, &m );
    for ( i = 1; i <= m; i ++ ){
        scanf ( "%d%d%d", &list[i].x, &list[i].y, &list[i].d );
    }
    sort ( list+1, list+m+1, cmp );
    for ( i = 1; i <= n; i ++ ) fa[i] = i;
    for ( i = 1; i <= m; i ++ ){
        int fx = ff (list[i].x), fy = ff (list[i].y);
        if ( fx != fy ){
            fa[fy] = fx;
            ins ( list[i].x, list[i].y, list[i].d );
            ins ( list[i].y, list[i].x, list[i].d );
        }
    }
    for ( i = 1; i <= n; i ++ ){
        if ( fw[i] == false ){ dep[i] = 1; dfs ( i, 0 ); }
    }
    scanf ( "%d", &q );
    for ( i = 1; i <= q; i ++ ){
        int x, y;
        scanf ( "%d%d", &x, &y );
        int fx = ff (x), fy = ff (y);
        if ( fx != fy ) printf ( "-1\n" );
        else printf ( "%d\n", lca ( x, y ) );
    }
    return 0;
}

  


 

以上是关于历年NOIP水题泛做的主要内容,如果未能解决你的问题,请参考以下文章

串简单题泛做

关于noip的一道水题.....

历年NOIP选题题解汇总

noip历年试题

历年NOIP中的搜索题

寒假训练计划