NOIp2017 题解

本文详细介绍了2017年NOIp竞赛中的题目,包括Day1的小凯的疑惑(最短路+记忆化搜索)、时间复杂度(栈模拟)和逛公园(最短路优化),以及Day2的奶酪(并查集/BFS)、宝藏(状压DP)和列队(线段树动态开点)。通过代码解析和问题探讨,帮助理解解题思路和算法应用。
摘要由CSDN通过智能技术生成

Day1

T1 小凯的疑惑

题目传送门

考场上打表搞了一个很奇怪的结论,化简后就是 a ∗ b − a − b a*b-a-b abab。具体证明现在还是不大会。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
LL a,b;
int main(){
    scanf("%lld%lld",&a,&b);
    if (a>b) swap(a,b);
    if (a==1){
        printf("0\n");
        return 0;
    }
    if (a==2){
        printf("%lld\n",b-2);
        fclose(stdin);
        fclose(stdout);
        return 0;
    }
    LL ans=(4+(a-3)*2+4)*(a-2)/2+1;
    ans+=(b-a-1)*(a-1);
    printf("%lld\n",ans);
    return 0;
}

T2 时间复杂度

题目传送门

一般用一个栈模拟,细节比较多。没什么好说的。

考场上写的代码只会统计第一个循环。。。然而还是有80。

当时太紧张就写得很丑。

代码:

#include<cctype>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 100
using namespace std;
struct Orz{
    char c;
    bool f;
}stack[MAXN+5];
int top,t,l,cmp,a[MAXN+5],ma;
int f;
char s[MAXN+5],sc[MAXN+5],sx[MAXN+5],sy[MAXN+5];
int main(){
    scanf("%d",&t);
    while (t--){
        memset(a,0,sizeof(a));
        f=0; top=0; cmp=0; ma=0;
        scanf("%d%s",&l,s);
        if (s[2]=='n') f=1;
        for (int i=0;s[i];i++)
            if (s[i]>='0'&&s[i]<='9')
                cmp=cmp*10+s[i]-48;
        int num=0;
        bool flag=false,fa=false,fl=false; if (l&1) flag=true;
        for (int i=1;i<=l;i++){
            int ff=0; char ss[2];
            scanf("%s",ss);
            ff=ss[0];
            if (ff=='F'){
                int c,x=0,y=0;
                scanf("%s%s%s",sc,sx,sy);
                c=sc[0];
                for (int j=0;sx[j];j++)
                    if (sx[j]>='0'&&sx[j]<='9')
                        x=x*10+sx[j]-48;
                for (int j=0;sy[j];j++)
                    if (sy[j]>='0'&&sy[j]<='9')
                        y=y*10+sy[j]-48;
                if (sx[0]=='n') x='n';
                if (sy[0]=='n') y='n';
                if (flag) continue;
                if (a[c-'a']){ flag=true; continue; }
                if (x=='n'&&y!='n') fl=true;
                if (x!='n'&&y!='n'&&x>y) fl=true;
                if (x!='n'&&y=='n') num++;
                if (x!='n'&&y=='n'&&(!fl)) fa=true,ma=max(ma,num);
                a[c-'a']++; 
                Orz p; p.c=c;
                if (x!='n'&&y=='n') p.f=true;
                else p.f=false;
                stack[++top]=p;
            }
            else{
                if (!top) { flag=true; continue; }
                if (stack[top].f) num--;
                a[stack[top--].c-'a']--;
                if (!top) fl=false;
            }
        }
        if (top) flag=true;
        if (flag){
            printf("ERR\n");
            continue;
        }
        if ((fa&&(f==0))||(ma!=cmp&&(f==1))){
            printf("No\n");
            continue;
        }
        printf("Yes\n");
    }
    return 0;
}

T3 逛公园

题目传送门

最短路+记忆化搜索

考场上用最短路优化一下就有60了。。。

先刷一遍反图最短路求出每个点到 n n n的最短路 d i s [ i ] dis[i] dis[i]

f [ i ] [ j ] f[i][j] f[i][j]表示到第 i i i个点,超出最短路的路程 ≤ j

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值