栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

CSP-J 2021解题报告

CSP-J 2021解题报告

放在前面:各位同学一定要好好复习初赛……不要像我一样初赛都没过……
1.P7909

作为第一题……肯定不会很难(我还是卡了一下TAT)

可以想到输出的结果一定是  0~(n-1)

关键在于是判断输出n-1还是其他

  1. L到R之间的区间超过n      输出(n-1)
  2. L到R之间的区间小于n      输出最大解(r%n)

上代码:

#include

using namespace std;

int n,l,r,a,b;

int main()
{
	cin>>n>>l>>r;
	a=l/n;
	b=r/n;
    //判断区间
	if(a==b) cout< 

理解一下应该不太难(相比于其他题解做法,这个要讨论的情况不会太多,不容易出错)


2.P7910

这道题的题目理解相对难一(hen)点(duo)

关键在于选择排序是个稳定排序(复习一下初赛知识——稳定排序有:希尔选择快速堆

还有就是解决超时问题

H 老师不喜欢过多的修改,所以他保证类型 1 的操作次数不超过 5000。

所以我们选择对类型1下手……!

关键点:操作类型1时顺便排序

还有就是一些……奇奇怪怪的错误

代码(虽然代码写的繁琐,但是思路还是很明确的……其实是我太菜):

#include
#include
#include

using namespace std;

int n,m,kind,x,v,ans;
struct number
{
	int a,ans;
}p[8005],b[8005];//b数组是为了方便转换

//p.a保存原数组
//p.ans是保存排序后的下标
//b为排序后的数组
//b.ans是排序前的下标(用于转换)
bool cmp(number x,number y)//sort
{
	if(x.a!=y.a) 
	return x.ay.ans;
	return x.a>y.a;//稳定排序下标也需要比较
}
bool l(number x,number y)//十分繁琐的判断是否可以交换
{
	if(x.a==y.a) return x.ans1;k--)
	{
		if(l(b[k],b[k-1]))//码代码小tip:当判断十分繁琐……再用一个函数写也不是不可以
        //(我这里调了好久)
		swap(b[k],b[k-1]);	 
	}
	for(int i=1;i<=n;i++) p[b[i].ans].ans=i;//转换说的就是这里
}



int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%d",&p[i].a),b[i].a=p[i].a,b[i].ans=i;//转换
	sort(b+1,b+1+n,cmp);//开头那个排序
	for(int i=1;i<=n;i++) p[b[i].ans].ans=i;//再转换
	for(int i=1;i<=m;i++)
	{
		scanf("%d",&kind);
		if(kind==1)
		{
			scanf("%d%d",&x,&v);
            //核心代码排序(其实这里可以用一个sort直接解决【如开头那个排序】……
            //为什么不用后文会提到
			if(v>p[x].a)
			right();
			if(v 

回到排序的问题(为什么不用sort直接解决?)

当然是因为超时呀……!

思考一下:

其实b数组一直都是有顺序的

当你改变某个元素的值时……你只需要判断它去那个位置就ok了

所以就有了那段繁琐的 left right

其实我的代码是比较……丑陋的(蒟蒻)
3.P7911

这道大模拟着实没有意义……直接看代码吧(可以说比较清晰了)

写了  的代码:

#include
#include
#include
#include
#include

using namespace std;

int n; 
string kind,save,num,str;
char s;
map cc;

bool abcd(string f)
{
    if(f.size()<=2&&f>="0") return true;
    if(f<="255"&&f.size()==3) return true;
    return false;
}

bool e(string f)
{
    if(f.size()<=4&&f>="0") return true;
    if(f<="65535"&&f.size()==5) return true;
    return false;
}

int ERR()
{
    cin>>str;
    int i=0;
    num="";
    while(str[i]>='0'&&str[i]<='9')
    num=num+str[i],i++;
    if(num[0]=='0'&&num.size()!=1) 
    {
        return -1;
    }

    if(abcd(num)==false)
    {
        return -1;
    }
    save=save+num;
    s=str[i];
    if(s!='.')
    {
        return -1;
    }
    save=save+s;

    i++;
    num="";
    while(str[i]>='0'&&str[i]<='9')
    num=num+str[i],i++;
    if(num[0]=='0'&&num.size()!=1) 
    {
        return -1;
    }
    if(abcd(num)==false)
    {
        return -1;
    }
    save=save+num;
    s=str[i];
    if(s!='.')
    {
        return -1;
    }
    save=save+s;

    i++;
    num="";
    while(str[i]>='0'&&str[i]<='9')
    num=num+str[i],i++;
    if(num[0]=='0'&&num.size()!=1) 
    {
        return -1;
    }
    if(abcd(num)==false)
    {
        return -1;
    }
    save=save+num;
    s=str[i];
    if(s!='.')
    {
        return -1;
    }
    save=save+s;

    i++;
    num="";
    while(str[i]>='0'&&str[i]<='9')
    num=num+str[i],i++;
    if(num[0]=='0'&&num.size()!=1) 
    {
        return -1;
    }
    if(abcd(num)==false)
    {
        return -1;
    }
    save=save+num;
    s=str[i];
    if(s!=':')
    {
        return -1;
    }
    save=save+s;

    i++;
    num="";
    while(str[i]>='0'&&str[i]<='9'&&i<=str.size()-1)
    num=num+str[i],i++;
    if(num[0]=='0'&&num.size()!=1) 
    {
        return -1;
    }
    if(e(num)==false)
    {
        return -1;
    }
    save=save+num;
    if(i!=str.size())
    {
        return -1;
    }
    return 0;//一定要记得!!!
}

int FAILS(int w)
{
    if(cc[save]!=0) return -1;
    else
    cc[save]=w;
    return 0;//一定要记得!!!
}

int FAILC()
{
    if(cc[save]==0) return -1;
    return 0;//一定要记得!!!
}

int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>kind;
        save="";
        if(kind=="Server")
        {
            if(ERR()==-1)
            {
                cout<<"ERR"< 

这是一个因为没加 return 0 而导致的惨案

我甚至写了个对拍程序……(检查大数据)

特别感谢 @ EdisonBa  帮我纠错……% 

 讨论指引……感兴趣可以康康http://luogu.com.cn/discuss/374673

同学们返回一定一定要加返回值啊……爆0惨案刻骨铭心……


4.P7912

怎么说……我还没有过……QWQ

(队列做法看起来似乎是正解,提交却超时QWQ)

思路:外面一层队列存放块,里面再用队列存水果

瞄了眼题解……似乎差不多呀……?

70分代码:

#include
#include
#include
#include
#include

using namespace std;

struct kkk
{
    queue a;//水果 
    queue b;//水果ID 
    int last;//最后一个水果 
}w;
void clear(queue& q) 
{
    queue empty;
    swap(empty, q);
}//清空队列 
int n,v,tt;
queue q;//块 
void defi()
{
    clear(w.a);
    clear(w.b);
    w.last=0;
}//清空w(这里应该会有更好的方法……奈何我太菜了) 

int main()
{
    scanf("%d",&n);
    defi();
    scanf("%d",&v);
    w.a.push(v);
    w.b.push(1);
    w.last=v;
    for(int i=2;i<=n;i++)
    {
        scanf("%d",&v);
        if(v==w.last)
        {
            w.a.push(v);
            w.b.push(i);
            w.last=v;
        }
        else
        {
            q.push(w);
            defi();
            w.a.push(v);
            w.b.push(i);
            w.last=v;
        }
    }
    q.push(w);
    kkk tail;
    tail.last=555;
    q.push(tail);//水果链的结尾(用于换行 
    tt=-1;
    while(q.size()>1)
    {
        kkk s=q.front();
        q.pop();
        if(s.last==555)//换行 
        {
            printf("n");
            tt=5;
            q.push(s);
            continue;
        }
        if(s.a.front()!=tt)//与前面的块不能合并 
        {
            printf("%d ",s.b.front());
            tt=s.a.back();
            s.a.pop();
            s.b.pop();      
        }
        if(s.a.empty()==false) q.push(s);//这个块水果拿完了 
    }

    return 0;
}
//似乎是O(n)做法……为啥超时TAT 

然后……就没有然后了(可以看看帖子) 

讨论指路https://www.luogu.com.cn/discuss/374841


没过初赛的惨案……ε=(´ο`*)))唉

CCF ta没有心

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/433926.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号