zzu 2024寒假训练day1(A-I)

题目链接

目录

1.A

2.B

3.C.

4.D

5.E

6.F

7.G

8.H

9.I


1.A

用数组的话,查找k和删除操作中查找x都是logn的操作,会超时,因此使用链表比较方便,用pos数组储存迭代器可弥补list不能随机访问的缺陷(复杂的题还是用静态链表吧).

#include
using namespace std;
const int maxn=1e5+5;
list::iterator pos[maxn];
bool erased[maxn];
int main()
{
    int n;
    cin>>n;
    listquelist;
    quelist.insert(quelist.begin(),1);
    pos[1]=quelist.begin();
    int k,p;
    for(int i=2;i<=n;i++)
    {
        cin>>k>>p;
        if(p==0)
        {
            pos[i]=quelist.insert(pos[k],i);
        }
        else
        {
            auto nextiter=next(pos[k]);
            pos[i]=quelist.insert(nextiter,i);
        }
    }
    int m,x;
    cin>>m;
    while(m--)
    {
        cin>>x;
        if(!erased[x])
        {
            quelist.erase(pos[x]);
            erased[x]=true;
        }
    }
    for(int&x:quelist)
    cout<

2.B

经典的栈问题 用num=num*10+s[i]求出操作数,再入栈,碰到运算符号,则取栈中的两个数运算,再将运算结果入栈.

//后缀表达式 遇到数字入栈 遇到符号取栈顶再入栈
#include
using namespace std;
int main()
{
    string s;
    cin>>s;
    stackst;
    int i=0;
    int num=0;
    for(int i=0;i='0')
        {
            num=num*10+(s[i]-'0');
        }
        else
        {
            if(s[i]=='+')
            {
                int temp1=st.top();
                st.pop();
                int temp2=st.top();
                st.pop();
                st.push(temp1+temp2);
            }
            else if(s[i]=='-')
            {
               int temp1=st.top();
                st.pop();
                int temp2=st.top();
                st.pop();
                st.push(temp2-temp1);
            }
            else if(s[i]=='*')
            {
              int temp1=st.top();
                st.pop();
                int temp2=st.top();
                st.pop();
                st.push(temp1*temp2);
            }
            else if(s[i]=='/')
            {
                int temp1=st.top();
                st.pop();
                int temp2=st.top();
                st.pop();
                st.push(temp2/temp1);
            }
        }
    }
    cout<

3.C.

用队列储存单词库,只是队列的大小有限制(虽然我用的是双端队列,但效果一样)

//机器翻译(队列题)
#include
using namespace std;
bool book[1005];
int main()
{
    dequeque;
    int n,m;
    cin>>n>>m;
    int ans=0;
    for(int i=0;i>t;
        if(!book[t])
        {
            if(que.size()==n)
            {
                int tmp=que.front();
                book[tmp]=false;
                que.pop_front();
            }
            que.push_back(t);
            book[t]=true;
            ans++;
        }
    }
    cout<

4.D

用小根堆储存种数,贪心思路是:取最小值和次小值合成一堆,再重复一样的动作

//小根堆 贪心
#include
using namespace std;
int main()
{
    priority_queue,greater>h;
    int n;
    cin>>n;
    for(int i=0;i>t;
        h.push(t);
    }
    int ans=0;
    for(int i=0;i

5.E

就是map的使用

//哈希表  map
#include
using namespace std;
int main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    mapmp;
    int n;
    cin>>n;
    int op,t;
    string s;
    for(int i=0;i>op;
        if(op==1)
        {
            cin>>s>>t;
            mp[s]=t;
            cout<<"OK"<<"\n";
        }
        else if(op==2)
        {
            cin>>s;
            if(mp.find(s)==mp.end())
            cout<<"Not found"<<"\n";
            else
            cout<>s;
            if(mp.find(s)==mp.end())
            cout<<"Not found"<<"\n";
            else
            {
              mp.erase(s);
              cout<<"Deleted successfully"<<"\n";
            }
        }
        else if(op==4)
        cout<

6.F

用map记录每个数的个数,在遍历每个数字 当前数字为A,就要找A-C有多少个(因为B=A-C)

//哈希 双指针 排序
#include
using namespace std;
#define int long long 
signed main()
{
    int n,c;
    cin>>n>>c;
    mapmp;
    vectorv(n);
    for(int i=0;i>v[i];
        mp[v[i]]++;
    }
    int ans=0;
    for(int i=0;i

7.G

用set记录发送过的消息,用string的find方法判断一个字符串是否含有"bie"

#include
using namespace std;
int main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    setse;
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        int m;
        cin>>m;
        int cnt=0;
        for(int i=0;i>s;
            if(s.find("bie")!=string::npos)
            {
                if(se.find(s)==se.end())
                {
                    se.insert(s);
                    cnt++;
                    cout<

8.H

遇左端点入栈,遇右端点与栈顶元素结合并将差值插入小根堆,c插入大根堆,用小的区间消化的大的c

#include
using namespace std;
#define int long long
signed main()
{
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
    stackleft;
    mapumap;
    priority_queuec;//大根堆
    priority_queue,greater>minus;//小根堆
    for(int i=0;i>l;
       umap[l]='l';
    }
    for(int i=0;i>r;
      umap[r]='r';
    }
    for(int i=0;i>t;
	   c.push(t); 
    }
    for(auto i:umap)
    {
        if(i.second=='l')
           left.push(i.first);
        else
            {
			if(!left.empty())
            {
                minus.push(i.first-left.top());
                left.pop();
            }
            }
    }
    int sum=0;
    for(int i=0;i

9.I

链表题

重点是找出死掉的怪物和死掉怪物左右的新邻居

1.数据的输入,链表的初始化连接

2.找出没一轮的怪物候选人(第一轮过后死的怪物的左右即为候选人,用set储存)

3.筛选新一轮的候选人,并重连链表,去除死掉的怪物

//输入攻击和输出 处理好pre和nxt a[0]=0 d[0]=2e9+5 nxt[n]=0 pre[1]=0
//set 候选怪物入列 死了的怪物的左右需要重判
//判断是否死亡
#include
using namespace std;
#define int long long 
const int maxn=3e5+5;
int a[maxn],d[maxn],pre[maxn],nxt[maxn];
int d1[maxn];//死亡的小鼠
bool died[maxn];//判断是否死亡
signed main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int t;
    cin>>t;
    while(t--)
    {
        memset(died,false,sizeof(died));
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
            cin>>a[i];
        for(int i=1;i<=n;i++)
            cin>>d[i];
        
        a[0]=0;d[0]=2e9+5;
        nxt[n]=0;
        
        for(int i=1;i<=n;i++)
        {
            pre[i]=i-1;
            nxt[i-1]=i;
        }

        setse;
        int cnt=0;
        for(int i=1;i<=n;i++)
        {
            se.insert(i);//第一批候选者
        }

        for(int i=1;i<=n;i++)//n轮
        {
            for(auto idx:se)
            {
                if(died[idx])continue;
                if(a[pre[idx]]+a[nxt[idx]]>d[idx])
                {
                    d1[++cnt]=idx;
                }
            }
            se.clear();
            for(int i=1,idx;i<=cnt;i++)
            {
                idx=d1[i];
                se.insert(pre[idx]);
                se.insert(nxt[idx]);
                nxt[pre[idx]]=nxt[idx];//链表连接
                pre[nxt[idx]]=pre[idx];
                died[idx]=true;
            }
            cout<

你可能感兴趣的:(算法)