2023.11.22做题笔记

打字练习

P5587 打字练习 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)


我靠,真服了,模拟模不明白不说,题目还有坑,范文也会有"<"。

我只写出来一半,有一种情况没有考虑到位,那就是如下:asbd<<<<<<<<<<<<s<<s,逆天玩意,正常人一般都不会这么干吧。

但是,但是,重点问题,<是推掉用新的代替,为什么没有想到用栈???为什么??因为我还是一只小蒟蒻qwq,懂了就好了,那就不贴栈的代码了,下面贴一个佬的代码

#include<bits/stdc++.h>
#pragma GCC optimize(3)
using namespace std;
const int N=1e4+5;
string s[N],t[N],s1;
long long n,m,cnt;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    while(getline(cin,s1),s1!="EOF"){
        n++;//读入字符串
        for(char i:s1)if(i=='<'){if(!s[n].empty())s[n].pop_back();}//模拟,如果是退格且string中还有字符就删掉一个
        else s[n].push_back(i);//否则加上去
    }
    while(getline(cin,s1),s1!="EOF"){
        if(++m>n)break;
        for(char i:s1)if(i=='<'){if(!t[m].empty())t[m].pop_back();}
        else t[m].push_back(i);//同上
        for(int i=0;i<min(t[m].size(),s[m].size());i++)cnt+=s[m][i]==t[m][i];//逐位比较
    }
    cin>>m;
    cout<<(long long)(cnt*60.0/m+0.5);//输出
}

用到了一些我现在看不懂的东西,觉得很“佬”,所以贴这篇。。。。。。

 


生活大爆炸版石头剪刀布

P1328 [NOIP2014 提高组] 生活大爆炸版石头剪刀布 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

是一道好题,我没有写,贴一篇佬的题解

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 200 + 10;
int n, na, nb, a[MAXN], b[MAXN], cnta, cntb;
int vs[5][5] = {{0,0,1,1,0},{1,0,0,1,0},{0,1,0,0,1},{0,0,1,0,1},{1,1,0,0,0}}; //得分表的处理 
int main()
{
    cin >> n >> na >> nb;
    for(int i = 0; i < na; i++) cin >> a[i];
    for(int i = 0; i < nb; i++) cin >> b[i];
    for(int i = 0; i < n; i++)
    {
        cnta += vs[a[i % na]][b[i % nb]]; //周期循环 
        cntb += vs[b[i % nb]][a[i % na]];
    }
    cout << cnta << " " << cntb << endl;
    return 0;
}

从中学到的东西:用vs[i][j]去制作一个表格,会方便许多。。。。。


玩具谜题

P1563 [NOIP2016 提高组] 玩具谜题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

这道题不难,直接模拟就可以;我先想到的是结构体链表,因为循环嘛,注意这样的题可以有一个小小的优化,就是内外和左右的叠加,然后贴代码

#include<bits/stdc++.h>
using namespace std;
struct node 
{
    int head;
    string name;
}a[100005];
int n,m,x,y;
int main()
{
    cin>>n>>m;
    for(int i=0;i<n;i++)
    {
        cin>>a[i].head>>a[i].name;
    }
    int now=0;
    for(int i=1;i<=m;i++)
    {
        cin>>x>>y;
        if(a[now].head==0&&x==0)now=(now+n-y)%n;
        else if(a[now].head==0&&x==1)now=(now+y)%n;
        else if(a[now].head==1&&x==0)now=(now+y)%n;
        else if(a[now].head==1&&x==1)now=(now+n-y)%n;
    }
    cout<<a[now].name<<endl;
    return 0;
}

佬的代码,我没有写,你会发现不用链表也可以qwq


乒乓球

P1042 [NOIP2003 普及组] 乒乓球 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

这道题,有一说一应该不难,为什么写进来捏,因为我是一只小蒟蒻,我在判断它比分的时候用了很质朴的方式,如果a==11,什么的以至于判断比赛结束很麻烦,但是佬就不同,佬想到了分差,就是相差的绝对值,qwq,下次记得考虑qwq


逆序对

P1908 逆序对 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

这道题啊,典,但是折磨了我很长时间,因为我计数出了点问题qwq附ac代码

#include<iostream>
using namespace std;

const int N=5000005;
int a[N];
long long ans=0;
int b[N];

void solution(int a[],int sta,int en)
{
    if(sta>=en)return;
    int c[N];
    int t=(sta+en)>>1;

    solution(a,sta,t);
    solution(a,t+1,en);
    
    int i=sta,j=t+1,k=0;
    while(i<=t && j<=en)
    {
        if(a[i]<=a[j])
            c[k++]=a[i++];
        else
        {
            ans+=t-i+1;
            c[k++]=a[j++];
        }
    }
    while(i<=t)c[k++]=a[i++];
    while(j<=en)c[k++]=a[j++];
    for(int l=sta,p=0;l<=en;l++,p++)a[l]=c[p];
}

int main()
{
    int n;
    cin>>n;
    for(int i=0;i<n;i++)cin>>a[i];
    solution(a,0,n-1);
    cout<<ans;
    system("pause");
    return 0;
}

这是我的,用归并去解(一般般),佬都是用树状数组去解的,贴一个佬的:

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 50000
using namespace std;
struct node
{
    int val,num;
}a[maxn];
int n;
int c[maxn];
int add(int x,int k)
{
    for(int i=x;i<=n;i+=i&(-i)) c[i]+=k;
}
int query(int x)
{
    int sum=0;
    for(int i=x;i>0;i-=i&(-i)) sum+=c[i];
    return sum;
}
int cmp(node x,node y)
{
    return x.val>y.val;
}
int ans;
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++) scanf("%d",&a[i].val),a[i].num=i;
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;i++)
    {
        add(a[i].num,1);
        ans+=query(a[i].num-1);
    }
    cout<<ans<<endl;
}

这道题可以去看看题解,里面有佬用线段树解,但是远远不止线段树,还介绍了线段树大法。。。。。

 

posted @ 2023-11-22 14:23  工作日摆烂  阅读(24)  评论(0)    收藏  举报