首页 > 其他分享 >NOIP模拟1

NOIP模拟1

时间:2022-11-02 16:47:15浏览次数:64  
标签:ch ve NOIP int 链表 -- maxn 模拟

A. 语言

想到小学英语老师一遍遍地强调:每个句子有且只有一个动词!!忽然给了我灵感。发现不是动词的部分AN可以自由组合,A可以这样连续A(AN),A(A(AN)),唯一不合法的情况就是A在末尾,也就是V分出来的前后两段中末尾只要有可能是N就Yes,判断一下就好了。

code
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int maxn = 1e5 + 3;

char s[maxn];
int T, n, zm[30], cnt, pos;
bool flag;

inline int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-')
        {
            f = -1;
        }
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        x = (x << 1) + (x << 3) + (ch^48);
        ch = getchar();
    }
    return x * f;
}

int main()
{
    freopen("language.in", "r", stdin);
    freopen("language.out", "w", stdout);
    
    T = read();
    while(T--)
    {
        for(int i=1; i<=26; i++)
        {
            zm[i] = read();
        }
        flag = 0; cnt = 0; pos = 0;
        scanf("%s", s+1); n = strlen(s+1);
        if(!(zm[s[n]-'a'+1] & 2))
        {
            printf("No\n"); continue;
        }
        for(int i=1; i<=n; i++)
        {
            if(zm[s[i]-'a'+1] == 4) cnt++, pos = i;
        }
        if(cnt > 1 || pos == 1) 
        {
            printf("No\n"); continue;
        }
        if(pos)
        {
            if(zm[s[pos-1]-'a'+1] & 4) printf("Yes\n");
            else printf("No\n");
        }
        else 
        {
            for(int i=2; i<n; i++)
            {
                if((zm[s[i]-'a'+1] & 4) && (zm[s[i-1]-'a'+1] & 2))
                {
                    flag = 1; printf("Yes\n"); break;
                }
            }
            if(!flag) printf("No\n");
        }
    }
    
    return 0;
}

 

B. 色球

->思考怎么写链表遇到了两个问题: 1.每一个链表大小开maxn,有maxn个位置,会MLE sol:链表占用的内存和是maxn,链表结构体只需要一个,其实这个和邻接链表存图很相似 2.链表分为pre和nxt,一会走pre一会走nxt判断起来太复杂 sol:双向链表都是中间pre和nxt都满着,两边空一个,用满的填空的来合并,从端点开始找满的那个是单向的 process: 无限容器,盲猜vector都会炸,所以搞了个什么回退把空间复杂度降到了O(n),结果还不如写个暴力呢。。 我居然都没有写个暴力保底。。考试策略差评
code
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int maxn = 2e5 + 3;

int n, m, ans;
typedef pair<int, int> pii;
vector<pii> ve[maxn];
char op[7];

inline int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-')
        {
            f = -1;
        }
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        x = (x << 1) + (x << 3) + (ch^48);
        ch = getchar();
    }
    return x * f;
}

int main()
{
    freopen("color.in", "r", stdin);
    freopen("color.out", "w", stdout);
    
    n = read(); m = read();
    while(m--)
    {
        scanf("%s", op);
        if(op[2] == 's')
        {
            int x = read(), y = read(), z = read();
            ve[z].push_back(pii(x, y));
        }
        else if(op[2] == 't')
        {
            int u = read(), v = read();
            int sz = ve[u].size();
            for(int x=sz-1; x>=0; x--)
            {
                ve[v].push_back(ve[u][x]);
            }
            ve[u].clear();
        }
        else 
        {
            int x = read(), z = read();
            while(x)
            {
                if((*--ve[z].end()).first < x) 
                {
                    x -= (*--ve[z].end()).first;
                    ve[z].erase(--ve[z].end());
                }
                else 
                {
                    ans = (*--ve[z].end()).second;
                    (*--ve[z].end()).first -= x;
                    if((*--ve[z].end()).first == 0) ve[z].erase(--ve[z].end());
                    break;
                }
            }
            printf("%d\n", ans);
        }
    }
    
    return 0;
}
为什么用链表比用vector优化?空间上:复制消耗的空间不存在了,直接操作 时间上,复制花费的循环不存在了,,所以最麻烦的操作就在于反向复制了?怪不得没有“不含询问3”的特殊数据 不过用数组模拟链表的话,用不了的内存还是要开满???那不就&*%¥#@*…… 但是如果只记录前驱后继,那又一定会丢失信息,所以每个“点”都需要详细信息 对每个位置开链表不一定分的那么清楚,连tot和箭头数组都要分开,一个就够了 在没有方向不变的时候,ch[0]代表靠近tail的上一个,ch[1]代表靠近head的上一个, 反向的过程,让下一个成为head,而原来的表尾只存在ch[1],那就只能跳ch[1],在跳的方向上删掉自己 导致下一个也只有一个选择,每个起点都一定只有一个选择 连续反向就导致ch[0]和ch[1]的灵活互换,双向链表正反来回变,可以解释为什么不直接在正向时填入ch[0]反向时填入ch[1] 那么所以为什么新点没有分类讨论?? 既然它没有讨论,那是不是就说明下文的比较也不重要?? 不是,新节点的ch肯定都是空的,这就是不分讨的理由!!
code
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int maxn = 3e5 + 3;

int n, m, tot, h[maxn], t[maxn];
char op[7];

inline int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-')
        {
            f = -1;
        }
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        x = (x << 1) + (x << 3) + (ch^48);
        ch = getchar();
    }
    return x * f;
}

struct line 
{
    int c, num, ch[2];
}p[maxn];

int main()
{
    freopen("color.in", "r", stdin);
    freopen("color.out", "w", stdout);
    
    n = read(); m = read();
    for(int i=1; i<=m; i++)
    {
        scanf("%s", op);
        if(op[2] == 's')
        {
            int x = read(), y = read(), z = read();
            p[++tot] = (line){y, x, h[z], 0};
            if(h[z]) p[h[z]].ch[0] ? (p[h[z]].ch[1] = tot) : (p[h[z]].ch[0] = tot);
            else t[z] = tot;
            h[z] = tot;
        }
        else if(op[2] == 'p')
        {
            int x = read(), y = read();
            while(p[h[y]].num < x)//猜对了,h等于0了,死循环了!!!
            {
                //printf("h[%d] = %d\n", y, h[y]);
                //printf("x = %d\n", x);
                if(!h[y]) exit(0);
                x -= p[h[y]].num;//另一个新发现是x=4之后再也不减小了??
                int nxt = p[h[y]].ch[0] | p[h[y]].ch[1];
                if(nxt)
                {
                    //找到错因了:比较的是下一个,删的也是下一个,我怎么删成自己了?!
                    p[nxt].ch[0] == h[y] ? (p[nxt].ch[0] = 0) : (p[nxt].ch[1] = 0);
                }
                h[y] = nxt;//这个写在外面,似乎也不重要因为保证了不合法情况不存在
            }
            p[h[y]].num -= x;
            printf("%d\n", p[h[y]].c);
        }
        else 
        {
            int x = read(), y = read();
            if(!h[x]) continue;
            if(h[y])
            {
                p[h[y]].ch[0] ? (p[h[y]].ch[1] = h[x]) : (p[h[y]].ch[0] = h[x]);
                p[h[x]].ch[0] ? (p[h[x]].ch[1] = h[y]) : (p[h[x]].ch[0] = h[y]);
            }
            else t[y] = h[x];
            h[y] = t[x];//t[y] = h[x]我憨了,顺序没了
            h[x] = t[x] = 0;
        }
    }
    
    return 0;
}
 

标签:ch,ve,NOIP,int,链表,--,maxn,模拟
From: https://www.cnblogs.com/Catherine2006/p/16851501.html

相关文章

  • 20221102模拟赛题解
    A-Holy思路由于要让最小值最大,不难想到二分答案。二分后将原矩阵中大于等于\(mid\)的值设为\(1\),小于的设为\(0\),然后将每一行压成二进制,存在两行满足要求当且仅当两......
  • 煤矿模拟安全事故应急演练清除员工麻痹大意等危险思想-深圳华锐视点
    煤矿一旦出事,必然损失惨重,而传统煤矿安全培训只能在地面上开展讲座,受多因素限制,学员难以真正进入井下作业现场,进行各种高风险操作模拟实训练习,培训效果自然不如其他行......
  • redis 5.0.5集群部署与故障模拟
    背景业务稳定性要求需要一套redis集群来保障因此采用rediscluster集群环境名称ip地址cpu内存master端口slave端口redis-65110.65.6.514c8G70017......
  • CSP & NOIP 2022 邮寄
    开坑了。2022/09/18上午在家看了一上午番。下午到CSSYZ门口,发现只有少部分同学已经到了,于是尾随一位女同学去了文具店,买了些笔。重新到校门口,打算去教室放下书包,中途......
  • P1044 [NOIP2003 普及组] 栈 (卡特兰数)
    [NOIP2003普及组]栈题目背景栈是计算机中经典的数据结构,简单的说,栈就是限制在一端进行插入删除操作的线性表。栈有两种最重要的操作,即pop(从栈顶弹出一个元素)和push(......
  • [Pyhton] SimPy 离散事件模拟框架详解 —— 以一个简单的汽车充电排队模拟为例
    目录一、背景知识二、SimPy讲解2.1SimPy概述2.2基本概念2.3一个汽车开开停停的例子2.4在走走停停过程中增加充电过程(过程交互)2.5共享资源三、后续参考链接附录二......
  • [单片机框架][driver层][ioctl] MCU模拟Linux注册驱动
    概念ioctl是设备驱动程序中设备控制接口函数,一个字符设备驱动通常会实现设备打开、关闭、读、写等功能,在一些需要细分的情境下,如果需要扩展新的功能,通常以增设ioctl()命......
  • STM32 HAL IIC软模拟
    IIC(Inter-IntegratedCircuit)其实是IICBus简称,所以中文应该叫集成电路总线,它是一种串行通信总线,使用多主从架构,由飞利浦公司在1980年代为了让主板、嵌入式系统或手机用以连......
  • N76E003 单片机 IIC 软模拟
    /*-----------------------------------------头文件-----------------------------------------*/#include"iic.h"/*-----------------------------------------宏定义-......
  • [单片机框架] [drivers] [hc4051] 8路模拟分流器
    1、概述74HC4051是--款八选一模拟开关电路,内置3个地址选择端(A0~A2),低有效的使能输入端(E),8路独立的输入/输出端(Y0~Y7)及公共输入/输出端(Z)。电路内部有8个双向模拟......