NOIp2017总结

版权声明:hhhhh https://blog.csdn.net/WT_cnyali/article/details/78620336

NOIp2017 反思总结

Day0

白天看了下sh的语法和vimrc,去__debug的博客看了一些黑科技
晚上睡的特别早。

Day1

起的比以往都早,感觉自己好勤快啊。老爸更早还买了早饭回来

T1

简直不敢相信自己的眼睛?几行完事简直不是T1风格。
考场上连公式都不信,硬要打表看看。

#include <bits/stdc++.h>
#define LL long long
using namespace std ;
int main() {
    freopen ( "math.in", "r", stdin ) ;
    freopen ( "math.out", "w", stdout ) ;
    LL a, b ;
    cin >> a >> b ;
    cout << a*b-a-b << endl ;
    return 0 ;
}
  • 最终100pt

T2

除了字符串略微恶心之外也没什么,但是我还是调了好久,主要原因还是对字符串处理不太熟练吧。
过了大样例就直接跑掉没管了,当时已经10:30了。
最终还是F语句里的数字只用了首位……
这还有90pt??辣鸡数据
先贴考场原文件吧

#include <bits/stdc++.h>
using namespace std ;
void File() {
    freopen ( "complexity.in", "r", stdin ) ;
    freopen ( "complexity.out", "w", stdout ) ;
}
const int maxm = 105 ;
int n, m, stk[maxm], top = 0 ;
char c[maxm], t[maxm], p[maxm] ;
bool vis[35] ;
int l[maxm], r[maxm], s[maxm], maxx[maxm] ;
void init() {
    top = 0 ;
    memset ( vis, 0, sizeof vis ) ;
    memset ( s, 0, sizeof s ) ;
    memset ( stk, 0, sizeof stk ) ;
    memset ( l, 0, sizeof l ) ;
    memset ( r, 0, sizeof r ) ;
    memset ( maxx, 0, sizeof maxx ) ;
}
void solve() {
    //puts("") ;
    int i ;
    bool ok = 1 ;
    scanf ( "%d %s", &m, c+1 ) ;
    for ( i = 1 ; i <= m ; i ++ ) {
        scanf ( "%s", p+1 ) ;
        if (p[1] == 'F') {
            ++top ;

            scanf ( "%s", p+1 ) ;
            if (vis[p[1]-'a']) {
                //printf ( "%d %c\n", i, p[1] ) ;
                ok = 0 ;
            }
            t[top] = p[1] ;
            vis[p[1]-'a'] = 1 ;

            scanf ( "%s", p+1 ) ;
            s[top] = 0 ;
            l[top] = r[top] = -1 ;
            if (p[1] == 'n') s[top] = -1 ;
            else l[top] = p[1]-'0' ;

            scanf ( "%s", p+1 ) ;
            if (p[1] == 'n') {
                if (s[top] == -1) s[top] = 0 ;
                else s[top] = 1 ;
            }
            else r[top] = p[1]-'0' ;

        } else {
            if (s[top] == -1) ;
            else if (s[top] > 0) {
                maxx[top-1] = max(maxx[top-1], s[top]+maxx[top]) ;
            } else if (l[top] <= r[top]) maxx[top-1] = max(maxx[top-1], maxx[top]) ;
            vis[t[top]-'a'] = 0 ;
            maxx[top] = 0 ;
            -- top ;
            if (top < 0) {
                //printf ( "%d top=%d\n", i, top ) ;
                ok = 0 ;
            }
        }
        //printf ( "top=%d s=%d maxx=%d\n", top, s[top], maxx[top] ) ;
    }
    //for ( i = 0 ; i <= m ; i ++ ) printf ( "t %d = %c\n", i, t[i] ) ;
    //for ( i = 0 ; i < 30 ; i ++ ) if (vis[i]) printf ( "%c\n", i+'a' ) ;
    if ((m&1) || ok==0 || top!=0) {
        //printf ( "m=%d ok=%d top=%d\n", m, ok, top ) ;
        puts("ERR") ;
        return ;
    }
    //for ( i = 0 ; i <= m ; i ++ ) printf ( "%d s=%d maxx=%d\n", i, s[i], maxx[i] ) ;
    int cc ;
    if (c[3] == '1') cc = 0 ;
    else {
        for ( cc = 0, i = 1 ; !isdigit(c[i]) ; i ++ ) ;
        for ( ; isdigit(c[i]) ; i ++ ) cc = cc*10 + c[i] - '0' ;
    }
    s[0] += maxx[0] ;
    //printf ( "cc=%d s=%d\n", cc, s[0] ) ;
    if (cc == s[0]) puts("Yes") ;
    else puts("No") ;
}
int main() {
    File() ;
    int _ ;
    scanf ( "%d", &_ ) ;
    while (_--) {
        init() ;
        solve() ;
    }
    return 0 ;
}
  • 最终90pt

真的辣鸡,连那里都忘记了

#include <bits/stdc++.h>
using namespace std ;
void File() {
    freopen ( "complexity.in", "r", stdin ) ;
    freopen ( "complexity.out", "w", stdout ) ;
}
const int maxm = 105 ;
int n, m, stk[maxm], top = 0 ;
char c[maxm], t[maxm], p[maxm] ;
bool vis[35] ;
int l[maxm], r[maxm], s[maxm], maxx[maxm] ;
void init() {
    top = 0 ;
    memset ( vis, 0, sizeof vis ) ;
    memset ( s, 0, sizeof s ) ;
    memset ( stk, 0, sizeof stk ) ;
    memset ( l, 0, sizeof l ) ;
    memset ( r, 0, sizeof r ) ;
    memset ( maxx, 0, sizeof maxx ) ;
}
void solve() {
    int i, x, j, len ;
    bool ok = 1 ;
    scanf ( "%d %s", &m, c+1 ) ;
    for ( i = 1 ; i <= m ; i ++ ) {
        scanf ( "%s", p+1 ) ;
        if (p[1] == 'F') {
            ++top ;
            scanf ( "%s", p+1 ) ;
            if (vis[p[1]-'a']) ok = 0 ;
            t[top] = p[1] ;
            vis[p[1]-'a'] = 1 ;
            scanf ( "%s", p+1 ) ;
            s[top] = 0 ;
            l[top] = r[top] = -1 ;
            if (p[1] == 'n') s[top] = -1 ;
            else {
                len = strlen(p+1) ;
                x = p[1]-'0' ;
                for ( j = 2 ; j <= len ; j ++ ) x = 10*x + p[j] - '0' ;
                l[top] = x ;
            }
            scanf ( "%s", p+1 ) ;
            if (p[1] == 'n') {
                if (s[top] == -1) s[top] = 0 ;
                else s[top] = 1 ;
            }
            else {
                len = strlen(p+1) ;
                x = p[1]-'0' ;
                for ( j = 2 ; j <= len  ; j ++ ) x = 10*x + p[j] - '0' ;
                r[top] = x ;
            }
        } else {
            if (s[top] == -1) ;
            else if (s[top] == 1) {
                maxx[top-1] = max(maxx[top-1], 1+maxx[top]) ;
            } else if (l[top] <= r[top]) maxx[top-1] = max(maxx[top-1], maxx[top]) ;
            vis[t[top]-'a'] = 0 ;
            maxx[top] = 0 ;
            -- top ;
            if (top < 0) ok = 0 ;
        }
    }
    if ((m&1) || ok==0 || top!=0) {
        puts("ERR") ;
        return ;
    }
    int cc ;
    if (c[3] == '1') cc = 0 ;
    else {
        for ( cc = 0, i = 1 ; !isdigit(c[i]) ; i ++ ) ;
        for ( ; isdigit(c[i]) ; i ++ ) cc = cc*10 + c[i] - '0' ;
    }
    s[0] += maxx[0] ;
    if (cc == s[0]) puts("Yes") ;
    else puts("No") ;
}
int main() {
    File() ;
    int _ ;
    scanf ( "%d", &_ ) ;
    while (_--) {
        init() ;
        solve() ;
    }
    return 0 ;
}

T3

本来觉得可以打出正解的,时间有点紧,也心急了。
瞎打一通发现除了浪费时间之外就毫无意义了。
最后想骗拓扑序的分都写WA了,真的菜。
懒得贴代码了,毫无意义。
- 最终20pt。
- 然而现在并没有改完,留坑。

下午晚上把农药的2h限制都打完了所以晚上只能玩电脑。
颓的不行。10:30睡并没有前一天早。

Day2

起的和昨天一样早,但是并不是很精神。
吃完早饭好些了,在大巴上精力就比较充沛了。

T1

简直在逗我笑,9:20打完跑了。
但是后来发现最大数据可以爆long long,心惊胆战了几天,但是redbag告诉我ccf并没有卡掉。
简直感激

#include <bits/stdc++.h>
#define LL long long
using namespace std ;
void File() {
    freopen ( "cheese.in", "r", stdin ) ;
    freopen ( "cheese.out", "w", stdout ) ;
}
const LL maxn = 1050 ;
LL n, m, h, r ;
bool vis[maxn] ;
struct node {
    LL x, y, z ;
} s[maxn] ;
LL dist ( node a, node b ) {
    LL d = 0 ;
    d = (a.x-b.x)*(a.x-b.x) ;
    d += (a.y-b.y)*(a.y-b.y) ;
    d += (a.z-b.z)*(a.z-b.z) ;
    return d ;
}
queue <LL> Q ;
void init() {
    memset ( vis, 0, sizeof vis ) ;
    while (!Q.empty()) Q.pop() ;
}
void solve() {
    LL i, x ;
    r = r*r ;
    for ( i = 1 ; i <= n ; i ++ )
        if (s[i].z*s[i].z <= r) {
            Q.push(i) ;
            vis[i] = 1 ;
        }
    while (!Q.empty()) {
        x = Q.front() ;
        Q.pop() ;
        for ( i = 1 ; i <= n ; i ++ )
            if (vis[i] == 0&&dist(s[x], s[i]) <= 4*r) {
                Q.push(i) ;
                vis[i] = 1 ;
            }
    }

    for ( i = 1 ; i <= n ; i ++ )
        if (vis[i] && (s[i].z-h)*(s[i].z-h) <= r) {
            puts("Yes") ;
            return ;
        }
    puts("No") ;
}
int main() {
    File() ;
    LL i, _ ;
    scanf ( "%lld", &_ ) ;
    while (_--) {
        init() ;
        scanf ( "%lld%lld%lld", &n, &h, &r ) ;
        for ( i = 1 ; i <= n ; i ++ )
            scanf ( "%lld%lld%lld", &s[i].x, &s[i].y, &s[i].z ) ;
        solve() ;
    }
    return 0 ;
}
  • 最终得分100pt

T2

想了一下,发现并不会,就先打了T3的30pt暴力。然后才回来看这一题。
看了下数据范围,简直就是写着状态压缩DP
然而发现好像还是不会。
最终弃了正解,目标改成70pt。
f[x][d][S] 表示以点x为根,到赞助商距离为d,点集为S的这棵子树的最小代价。顺便记下树的边权和。
式子好推的很,枚举子树合并即可。
mmp,最后出来才发现这是正解???没有什么优化就交了???
不过还是怪自己不会枚举子集的骚操作。

先贴下考场代码

#include <bits/stdc++.h>
#define LL long long
using namespace std ;
void File() {
    freopen ( "treasure.in", "r", stdin ) ;
    freopen ( "treasure.out", "w", stdout ) ;
}
const LL maxn = 15, maxS = (1<<12)+5, zhf = 1e9 ;
LL n, m, g[maxn][maxn], f[maxn][maxn][maxS] ;
LL bt[maxS], v[maxn][maxn][maxS] ;
bool have ( LL s, LL x ) {
    s >>= x-1 ;
    return s&1 ;
}
LL check_min ( LL &a, LL b ) { return a = a<b? a:b ; }

int main() {
    File() ;
    LL rec, d, i, j, S, s, s1, s2, x, u ;
    scanf ( "%lld%lld", &n, &m ) ;
    S = (1<<n)-1 ;
    for ( i = 0 ; i <= n ; i ++ )
        for ( j = 0 ; j <= n ; j ++ ) {
            g[i][j] = zhf ;
            for ( s = 0 ; s <= S ; s ++ )
                f[i][j][s] = zhf ;
        }
    for ( i = 1 ; i <= m ; i ++ ) {
        scanf ( "%lld%lld%lld", &x, &u, &rec ) ;
        check_min(g[x][u], rec) ;
        g[u][x] = g[x][u] ;
    }

    bt[0] = 0 ;
    for ( i = 1 ; i <= S ; i ++ ) bt[i] = bt[i>>1]+(i&1) ;

    for ( i = 1 ; i <= n ; i ++ )
        for ( j = 0 ; j <= n ; j ++ )
            f[i][j][1<<(i-1)] = 0 ;

    int bit ;
    for ( bit = 2 ; bit <= n ; bit ++ )
        for ( s = 0 ; s <= S ; s ++ ) {
            if (bt[s] != bit) continue ;
            for ( s1 = 0 ; s1 <= S ; s1 ++ ) {
                if (bt[s1]==0 || bt[s1] >= bit) continue ;
                s2 = s^s1 ;
                if ((s1&s2)!=0 || (s1|s2)!=s) continue ;
                for ( x = 1 ; x <= n ; x ++ ) {
                    if (have(s1,x)==0) continue ;
                    for ( u = 1 ; u <= n ; u ++ ) {
                        if (have(s2,u)==0) continue ;
                        if (g[x][u] == zhf) continue ;
                        for ( d = 1 ; d <= n ; d ++ ) {
                            rec = f[x][d-1][s1] + f[u][d][s2] + d*g[x][u] ;
                            if (f[x][d-1][s] > rec) {
                                f[x][d-1][s] = rec ;
                                v[x][d-1][s] = v[x][d-1][s1] + v[u][d][s2] + g[x][u] ;
                            } else if (f[x][d-1][s] == rec) {
                                check_min(v[x][d-1][s], v[x][d-1][s1]+v[u][d][s2]+g[x][u]) ;
                            }
                        }
                    }
                }
            }
        }

    LL ans = zhf ;
    for ( i = 1 ; i <= n ; i ++ )
        check_min(ans, f[i][0][S]) ;
    printf ( "%lld\n", ans ) ;
    return 0 ;
}
  • 最终得分80pt。

然后改了一点枚举方法就行。

T3

直接模拟。懒得贴代码了。
还没改,留坑。
- 最终得分30pt

中午聚完餐,回家睡了觉好的。
晚上嘛……
( ̄▽ ̄)

After All

  • 最终得分420,全省排名44。
    考试的时候坑自己,两天T2煮熟的鸭子都飞了。(雾)
    考试的时候心态明显没有平常好,考前20min还在床上?(大雾)
    不过考试的时候会发挥低于正常水平也是意料之中的事情,都过去了也不要再多说了。

  • 接下来干什么?有些迷茫,先搞搞文化休息一下脑袋吧。
    现在的化学课都成了美术课了,还有翻生物、化学书就像字典???

  • 不打算退组,但是这个星期也不打算停课。
    不如颓颓文化,某些人说的好听点是要冲冬令营实际上不就是在逃避文化课?

  • 和猫还有赛克做了下ACM北京的同步赛,我就是去搞笑(混饭吃)的?
    代码能力奇差。

  • 准备趁这点时间把不会的东西都学了,但是绝对不能把脑袋做傻。
    换了个座位,在机房少搞颓。
    坐在fastest旁边感觉快到模糊,瞎写了几道杜教筛。
    还把redbag赶到一边去了,(然而她似乎并没有怼我

11-23:逃课搞竞赛被抓,偷鸡不成蚀把米,很不爽2333

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页