2016 NOIP提高组复赛解题报告 C++

来源:互联网 发布:淘宝尺寸勾选 编辑:程序博客网 时间:2024/06/06 19:46

原文网址:http://blog.csdn.net/yhf_2015/article/details/53453562#t0

DAY1 T1 玩具谜题

题目来源:洛谷 1563

吐槽:

对NOIP出题人“魔法师”英语单词拼错表示(滑稽)。

思路:

模拟操作过程,分类讨论即可。 
时间复杂度:O(n+m)

代码:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;struct node{    int dir;    char name[15];};node p[100010];int n, m;int main(){    scanf("%d%d", &n, &m);    for(int i = 1; i <= n; i ++) scanf("%d%s", &p[i].dir, p[i].name+1);    int now = 1;    for(int i = 1; i <= m; i ++){        int a, b;        scanf("%d%d", &a, &b);        if(p[now].dir == 0){            if(a == 0) now = ((now - b) % n + n) % n;            else now = (now + b) % n;        }else{            if(a == 0) now = (now + b) % n;            else now = ((now - b) % n + n) % n;        }        if(now == 0) now = n;    }    printf("%s", p[now].name+1);    return 0;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30


代码:

#include <cstdio>#include <cstring>#include <iostream>#include <cstdio>using namespace std;const int maxn = 300010;struct node{    int begin, end, lca, len;};node p[maxn];int n, m, val[maxn];int _first[maxn], _next[maxn*2], _to[maxn*2], cnt;int ins1[maxn], ins2[maxn], del1[maxn], del2[maxn];int nxt[maxn*4], v[maxn*4], cnt1;int deep[maxn], up[maxn][20];int ans[maxn];int ct1[maxn*2], ct2[maxn*2];inline void add1(int a, int b, int c){    nxt[++cnt1] = ins1[a];    v[ins1[a] = cnt1] = c;    nxt[++cnt1] = del1[b];    v[del1[b] = cnt1] = c;}inline void add2(int a, int b, int c){    nxt[++cnt1] = ins2[a];    v[ins2[a] = cnt1] = c;    nxt[++cnt1] = del2[b];    v[del2[b] = cnt1] = c;}inline void add(int a, int b){    _next[++cnt] = _first[a];    _to[_first[a] = cnt] = b;}void dfs(int x){    for(int i = 1; i <= 18; i ++){        up[x][i] = up[up[x][i-1]][i-1];    }    for(int i = _first[x]; i; i = _next[i]){        if(_to[i] == up[x][0]) continue;        up[_to[i]][0] = x, deep[_to[i]] = deep[x]+1;        dfs(_to[i]);    }}void lca(){    for(int ii = 1; ii <= m; ii ++){        int x = p[ii].begin, y = p[ii].end;        if(deep[x] < deep[y]) swap(x, y);        if(deep[x] != deep[y])            for(int i = 18; i >= 0; i --)                if(deep[up[x][i]] >= deep[y]) x = up[x][i];        if(x != y){            for(int i = 18; i >= 0; i --)                if(up[x][i] != up[y][i]) x = up[x][i], y = up[y][i];            x = up[x][0];        }        p[ii].lca = x;        p[ii].len = deep[p[ii].begin] - deep[x] + deep[p[ii].end] - deep[x];    }}inline void dfs1(int x){    ans[x] = - ct1[deep[x]+val[x]] - ct2[deep[x]-val[x]+n];    for(int i = _first[x]; i; i = _next[i]){        if(_to[i] == up[x][0]) continue;        dfs1(_to[i]);    }    for(int i = ins1[x]; i; i = nxt[i]) ct1[v[i]] ++;    for(int i = del1[x]; i; i = nxt[i]) ct1[v[i]] --;    for(int i = ins2[x]; i; i = nxt[i]) ct2[v[i]+n] ++;    for(int i = del2[x]; i; i = nxt[i]) ct2[v[i]+n] --;    ans[x] += ct1[deep[x]+val[x]] + ct2[deep[x]-val[x]+n];}int main(){    scanf("%d%d", &n, &m);    for(int i = 1; i < n; i ++){        int a, b;        scanf("%d%d", &a, &b);        add(a, b), add(b, a);    }    deep[1] = 1, dfs(1);    for(int i = 1; i <= n; i ++) scanf("%d", &val[i]);    for(int i = 1; i <= m; i ++) scanf("%d%d", &p[i].begin, &p[i].end);     lca();    for(int i = 1; i <= m; i ++){        add1(p[i].begin, up[p[i].lca][0], deep[p[i].begin]);        add2(p[i].end, p[i].lca, deep[p[i].end]-p[i].len);    }    dfs1(1);    for(int i = 1; i < n; i ++) printf("%d ", ans[i]); printf("%d", ans[n]);    return 0;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90



代码:

#include <cstdio>#include <iostream>#include <cstring>#include <algorithm>using namespace std;const int inf = 2e9;int n, m, v, e;int a1[2010], a2[2010];double dp[2010][2010][2], dis[310][310], w[2010], ans;int main(){    scanf("%d%d%d%d", &n, &m, &v, &e);    for(int i = 1; i <= n; i ++) scanf("%d", &a1[i]);    for(int i = 1; i <= n; i ++) scanf("%d", &a2[i]);    for(int i = 1; i <= n; i ++) scanf("%lf", &w[i]);    for(int i = 0; i <= v; i ++)        for(int j = 0; j <= v; j ++)            if(i == j) dis[i][j] = 0;            else dis[i][j] = inf;    for(int i = 1; i <= e; i ++){        int a, b; double c;        scanf("%d%d%lf", &a, &b, &c);        dis[a][b] = min(dis[a][b], c);        dis[b][a] = min(dis[b][a], c);    }     for(int k = 1; k <= v; k ++)        for(int i = 1; i <= v; i ++)            for(int j = 1; j <= v; j ++)                if(dis[i][j] > dis[i][k]+dis[k][j])                    dis[i][j] = dis[i][k]+dis[k][j];    for(int i = 0; i <= n; i ++)        for(int j = 0; j <= m; j ++)            dp[i][j][0] = dp[i][j][1] = inf;    dp[1][0][0] = 0;    dp[1][1][1] = 0;    for(int i = 2, up; i <= n; i ++){        up = min(i, m);        for(int j = 0; j <= up; j ++){            dp[i][j][0] = min(dp[i][j][0], dp[i-1][j][0]                        +dis[a1[i]][a1[i-1]]);            dp[i][j][0] = min(dp[i][j][0], dp[i-1][j][1]                        +dis[a1[i]][a2[i-1]]*w[i-1]                        +dis[a1[i]][a1[i-1]]*(1-w[i-1]));            if(j-1 >= 0) dp[i][j][1] = min(dp[i][j][1], dp[i-1][j-1][0]                        +dis[a2[i]][a1[i-1]]*w[i]                        +dis[a1[i]][a1[i-1]]*(1-w[i]));            if(j-1 >= 0) dp[i][j][1] = min(dp[i][j][1], dp[i-1][j-1][1]                        +dis[a2[i]][a2[i-1]]*w[i]*w[i-1]                        +dis[a2[i]][a1[i-1]]*w[i]*(1-w[i-1])                        +dis[a1[i]][a2[i-1]]*(1-w[i])*w[i-1]                        +dis[a1[i]][a1[i-1]]*(1-w[i])*(1-w[i-1]));        }    }    ans = inf;    for(int i = 0; i <= m; i ++) ans = min(ans, min(dp[n][i][0], dp[n][i][1]));    printf("%.2lf", ans);    return 0;} 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57


代码:

#include <cstdio>#include <iostream>using namespace std;int T, k;int sum[2010][2010], val[2010][2010];int a[10010], b[10010], p1, p2;int main(){    scanf("%d%d", &T, &k);    for(int i = 1; i <= T; i ++){        scanf("%d%d", &a[i], &b[i]);        p1 = max(p1, a[i]);        p2 = max(p2, b[i]);    }    for(int i = 0; i <= p1; i ++){        for(int j = 0; j <= min(p2, i); j ++){            if(j == 0){val[i][j] = 1;continue;}            val[i][j] = (val[i-1][j] + val[i-1][j-1]) % k;            if(val[i][j] == 0) sum[i][j] = 1;        }    }    for(int i = 1; i <= p1; i ++){        for(int j = 1; j <= p2; j ++){            sum[i][j] = sum[i-1][j] + sum[i][j-1] + sum[i][j] - sum[i-1][j-1];        }    }    for(int i = 1; i <= T; i ++){        printf("%d\n", sum[a[i]][b[i]]);    }    return 0;} 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30


代码:

#include <cstdio>#include <iostream>#include <algorithm>#define MAX(a,b) (((a)>(b))?(a):(b))#define MIN(a,b) (((a)<(b))?(a):(b))using namespace std;inline int gt(){      char _ch = ' ';      int _num = 0, _op = 1, _ok = 0;      while(1){        _ch = getchar();        if(_ch == '-') _op *= -1;          else if(_ch >= '0' && _ch <= '9') _num = _num*10 + _ch - '0', _ok = 1;          else if(_ok) return _op * _num;     } }  int n, m, q, u, v, t;int left1;int len[100010], q1[8000010], q2[8000010];int out[1000010], cnt;int main(){    scanf("%d%d%d%d%d%d", &n, &m, &q, &u, &v, &t);    for(int i = 1; i <= n; i ++) len[i] = gt();    sort(len+1, len+1+n);    int p1 = 1, p2 = 0, p3 = 1, p4 = 0, p5 = n, now = 0;    for(int i = 1; i <= m; i ++){        if(p5 >= 1 && len[p5] >= MAX(q1[p1], q2[p3])) now = len[p5--] + left1;        else if(p1 <= p2 && q1[p1] >= q2[p3]) now = q1[p1++] + left1;        else if(p3 <= p4) now = q2[p3++] + left1;        if(i%t == 0) out[++cnt] = now;        left1 += q;        int new1 = ((long long)now*(long long)u)/(long long)v;        int new2 = now - new1;        q1[++p2] = MAX(new1, new2) - left1;        q2[++p4] = MIN(new1, new2) - left1;    }    for(int i = 1; i <= cnt; i ++) printf("%d ", out[i]);    printf("\n");    for(int i = 1, w = 0; i <= n+m; i ++, w = 0){        if(p5 >= 1 && len[p5] >= MAX(q1[p1], q2[p3])) w = len[p5--] + left1;        else if(p1 <= p2 && q1[p1] >= q2[p3]) w = q1[p1++] + left1;        else if(p3 <= p4) w = q2[p3++] + left1;        if(i%t != 0) continue;        printf("%d ", w);    }    return 0;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47



代码:

#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;const double eps = 0.000000001;struct point{    double x, y;};int T, n, m, ans = 1e9;point p[25];int num[25][25], dp[300010];int calc(double a, double b){    int res = 0, now = 1;    for(int i = 1; i <= n; i ++, now <<= 1){        double t = a*p[i].x*p[i].x+b*p[i].y;        if(abs(a*p[i].x*p[i].x+b*p[i].x-p[i].y) < eps){            res |= now;        }    }    return res;}int bits(int x){    int res = 0;    for(int i = 1; i <= n; i ++, x >>= 1) if((x&1) == 0) res ++;    return res;}int main(){    scanf("%d", &T);    while(T--){        scanf("%d%d", &n, &m);        for(int i = 1; i <= n; i ++){            scanf("%lf%lf", &p[i].x, &p[i].y);        }        memset(dp, 63, sizeof(dp));        memset(num, 0, sizeof(num));        ans = 1e9;        for(int i = 1; i <= n; i ++){            for(int j = i+1; j <= n; j ++){                if(i == j) continue;                if(abs(p[i].x-p[j].x) < eps) continue;                double a = (p[i].y*p[j].x-p[j].y*p[i].x)/(p[i].x*p[i].x*p[j].x-p[j].x*p[j].x*p[i].x);                if(a >= 0) continue;                double b = (p[i].y-a*p[i].x*p[i].x)/p[i].x;                num[i][++num[i][0]] = calc(a,b);            }         }        int MAX = (1<<n)-1;        dp[0] = 0;        for(int i = 0; i <= MAX; i ++){            int now = 0;            for(int j = 1, w = 1; j <= n; j ++, w <<= 1){                if((w&i) == 0){now = j;break;}            }            if(now == 0) continue;            dp[i|(1<<(now-1))] = min(dp[i|(1<<(now-1))], dp[i] + 1);            for(int j = 1; j <= num[now][0]; j ++){                dp[i|num[now][j]] = min(dp[i|num[now][j]], dp[i] + 1);            }        }        printf("%d\n", dp[MAX]);    }    return 0;}

原创粉丝点击