zoukankan      html  css  js  c++  java
  • CODEFORCE ROUND #625 DIV2

    不得不说cf题目都是毒瘤,一篇读下来我头都裂开了 (哭)

    个人认为这次的大坑点是E题 不谈有生之年的F题

    和平常一样A,B,C都是思维题不过这次C题有坑还是贴一下

    C题:

    https://codeforces.ml/contest/1321/problem/C

    题目大意就是给你n个字母,这个字母能被删除的条件是相邻的字母存在ASCII比他小1,问最多能删几个字母。

    这里的坑就是你当前枚举的最高字母要多遍历几遍,如果只遍历一遍那

    bbbbbbbb a bbbbb这种样例就会输出a前面一个加后面所有b的个数这样明显不对

    刚开始不知道string有erase函数搞得我头皮发麻

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<set>
    #include<list>
    #include<vector>
    #include<string>
    using namespace std;
    const int N=107;
    int n,ans;
    string s;
    int main()
    {
    	scanf("%d",&n);
    	getchar();
    	cin>>s;
    	for(int i='z';i>='a';i--)
    	{
    		for(int k=100;k>=0;k--)//多遍历几次
    		{
    			for(int j=0;j<s.size();j++)
    			{
    				if(i==s[j])
    				{
    					if(s[j]-s[j-1]==1||s[j]-s[j+1]==1)
    					{
    						ans++;
    						s.erase(j,1);
    						j--;
    					}
    				}
    			}
    		} 
    	} 
    	printf("%d",ans);
    	return 0;
    } 
    

      

    D题:

    https://codeforces.ml/contest/1321/problem/D

    题目大意就是n个点m条单向边,没有重边自环大概 给你一条初始路径(u,v),判断这条路径上的点是否符合最短路径,如果不符合就会重新导航问你最大和最小重新导航的次数比如(u,v)=1,2,3,4有这样一个图

    从1到4的最短路是1,5,4而路径会从1到2,不满足最短路就重新导航,2到4的最短路有2, 3, 4,2,6,4两条,若求最大值则系统应显示出264这样从2到3系统就会重新导航一次,如果系统本身显示的是234则从2到3满足路线就不会重新导航(求最小值)

    想想最短路的定义,dis i=dis j+w则是i到j的最短路这里判断固定路线z中相邻两点是不是的最短路只需判断dis[a1]?=dis[a2]+1

    如果等于:求最小值则ansminn不用加,求最大值则枚举a1的子节点若还存在一条最短路(dis children==dis a2)则ansmaxn++否则ansmaxn不加

    如果不想等则肯定要重新导航ansminn,ansmaxn都加

    求所有点到终点的最短路要反向建图

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<set>
    #include<list>
    #include<vector>
    #include<string>
    #include<queue>
    using namespace std;
    const int N=2e5+7,inf=0x3f3f3f3f;
    int n,m,ansmaxn,ansminn,x,y,k,a[N],dis[N];
    bool use[N];
    queue < int > q;
    vector < int > f1[N],f[N];
    void spfa(int x)
    {
    	for(int i=1;i<=n;i++)
    		dis[i]=inf;
    	//memset(dis,inf,sizeof(dis));
    	dis[x]=0;
    	q.push(x);
    	while(!q.empty())
    	{
    		int temp=q.front();
    		q.pop();
    		use[temp]=0;
    		for(int i=0;i<f[temp].size();i++)
    		{
    			int xx=f[temp][i];
    			if(dis[xx]>dis[temp]+1)
    			{
    				dis[xx]=dis[temp]+1;
    				if(use[xx]==0)
    				{
    					use[xx]=1;
    					q.push(xx);
    				}
    			}
    		}
    	}
    	return ;	
    }
    int main()
    {
    	scanf("%d %d",&n,&m);
    	for(int i=1;i<=m;i++)
    	{
    		scanf("%d %d",&x,&y);
    		f[y].push_back(x);//反向建图求dis
    		f1[x].push_back(y);//正向建图求子节点
    	}
    	scanf("%d",&k);
    	for(int i=1;i<=k;i++)
    		scanf("%d",&a[i]);
    	spfa(a[k]);
    	/*for(int i=1;i<=n;i++)
    	{
    		printf("%d ",dis[i]);
    	}*/
    	for(int i=1;i<k;i++)
    	{
    		if(dis[a[i]]==dis[a[i+1]]+1)
    		{
    			for(int j=0;j<f1[a[i]].size();j++)//枚举子节点
    			{
    				int temp=f1[a[i]][j];
    				if(dis[temp]==dis[a[i+1]]&&temp!=a[i+1])
    				{
    					ansmaxn++;
    					break;
    				}
    			}
    		}
    		else
    		{
    			ansmaxn++;
    			ansminn++;
    		}
    	}
    	printf("%d %d",ansminn,ansmaxn);
    	return 0;
    } 
    

      

    E题:

    这题坑我快5个小时

    现在过了我只想默默说一句 f**k

    题目大意是输入n,m,p有n个攻击装备,m个防御装备,p个怪物每个怪物被打败后都会有钱并且怪物每个只能打一次

    攻击装备和防御装备各买一个(即使怪物得到的钱很少也要买),且装备都有两个值 attack ,cost

    能打败怪物的条件是n attack>p def && m defense>p atk注意怪物是先输入def再是atk而装备相反。

    求获得的利润最大值 打败怪物获得的钱-装备花费的钱

    后来才知道这样的东西叫 二维偏序  听说624的F题也是这个?!!

    就是先将一维x放进线段树维护,另一维y排序,然后根据枚举的y ask线段树得出答案

    这种代码是用一种特殊的方式排序,后来直接o1查询 值得借鉴

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<set>
    #include<list>
    #include<vector>
    #include<string>
    #include<queue>
    #include<algorithm>
    using namespace std;
    const int N=2e5+7,M=1e6+5;
    const long long inf=0xfffffffff;
    int n,m,p;
    long long ca[M+5],cb[M+5],acost,bcost,a[N],b[N],ans=-inf;
    //ca,cb数组小心越界 
    struct node 
    {
    	long long at,w,def;//atk==x装备的def==x 
    	bool operator <(const node &t)const{return def<t.def;}
    }c[N];
    struct node3
    {
    	long long sum,maxn,add;
    }t[M*4];
    long long max(long long x,long long y)
    {
    	if(x>y)
    		return x;
    	return y;
    }
    void built(int p,int l,int r)
    {
    	t[p].add=0;
    	if(l==r)
    	{
    		t[p].maxn=-cb[l];
    		//t[p].sum=-b[l].w;
    		return ;
    	}
    	int mid=(l+r)/2;
    	built(p*2,l,mid);
    	built(p*2+1,mid+1,r);
    	t[p].maxn=max(t[p*2].maxn,t[p*2+1].maxn);
    	//t[p].sum=t[p*2].sum+t[p*2+1].sum;
    }
    void push_tag(int p,int l,int r)
    {
    	if(t[p].add)
    	{
    		t[p*2].add+=t[p].add;
    		t[p*2+1].add+=t[p].add;
    		t[p*2].maxn+=t[p].add;
    		t[p*2+1].maxn+=t[p].add;
    		t[p].add=0;
    	}
    	return ;
    }
    void push_down(int p)
    {
    	t[p].maxn=max(t[p*2].maxn,t[p*2+1].maxn);
    }
    void up(int p,int qx,int zx,int gl,int gr,int k)//区间加操作 
    {
    	if(qx>=gl&&zx<=gr)
    	{
    		t[p].add+=k;
    		t[p].maxn+=k;
    		return ;
    	}
    	int mid=(qx+zx)/2;
    	push_tag(p,qx,zx);
    	if(gl<=mid)
    		up(p*2,qx,mid,gl,gr,k);
    	if(gr>mid)
    		up(p*2+1,mid+1,zx,gl,gr,k);
    	push_down(p);
    	return ;
    }
    
    long long askmaxn(int p,int qx,int zx,int gl,int gr)//查询最大值 
    {
    	if(qx>=gl&&zx<=gr)
    	{
    		return t[p].maxn;
    	}
    	int mid=(qx+zx)/2;
    	long long ans=-inf;
    	push_tag(p,qx,zx);
    	if(gl<=mid)	
    		ans=max(ans,askmaxn(p*2,qx,mid,gl,gr));
    	if(gr>mid)
    		ans=max(ans,askmaxn(p*2+1,mid+1,zx,gl,gr));
    	return ans;
    }
    int main()
    {
    	scanf("%d %d %d",&n,&m,&p);
    	for(int i=1;i<=M+1;i++)
    	{
    		ca[i]=inf;//攻击为i时所要的最小的钱 
    		cb[i]=inf;//防御为i时所要的最小的钱 
    	}
    	for(int i=1;i<=n;i++)
    	{	
    		scanf("%lld %lld",&a[i],&acost);
    		ca[a[i]]=min(ca[a[i]],acost); 
    	} 
    	for(int i=1;i<=m;i++)
    	{
    		scanf("%lld %lld",&b[i],&bcost);
    		cb[b[i]]=min(cb[b[i]],bcost);
    	}
    	for(int i=M;i>=1;i--)
    	{
    		ca[i]=min(ca[i],ca[i+1]);
    		cb[i]=min(cb[i],cb[i+1]);//如果防御力为i存在铠甲则有i-1防御力铠甲的代价最小仍为cb[i] 
    	}
    	built(1,1,M);//防御力线段树 
    	for(int i=1;i<=p;i++)
    		scanf("%lld %lld %lld",&c[i].def,&c[i].at,&c[i].w);
    	sort(c+1,c+p+1);//monster 防御力从小到大 
    	ans=-ca[1]-cb[1];
    	//printf("%lld %lld
    ",ca[1],cb[1]);
    	for(int i=1;i<=p;i++)
    	{
    		up(1,1,M,c[i].at+1,M,c[i].w); 
    		//先假设剑的攻击力都足以破防,则防御力大于等于c[i].at+1的装备全部可以得到c[i].w的钱
    		ans=max(ans,askmaxn(1,1,M,1,M)-ca[c[i].def+1]); 
    		//防御力已经满足则只需要减去攻击力大于等于c[i].def+1的购买费用即可 
    		//因为防御力已经排序了,所有后来的monster防御力一定大于先前的
    		//当前选择的剑攻击力一定能破之前怪的防此时满足up的假设 故up函数成立 
    	}
    	printf("%lld",ans);
    	return 0;
    } 
    

      

    这种是我最开始写的,因为inf 是int 类型(和上面代码开始犯的错一样)没过我还以为思路或者线段树写错了...结果没错

    就是这个const long long inf=0xfffffffff坑死个人

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<set>
    #include<list>
    #include<vector>
    #include<string>
    #include<queue>
    #include<algorithm>
    using namespace std;
    const int N=2e5+7;
    const long long inf=0xfffffffff;
    int n,m,p,pos1,pos2,pos3;
    long long mat[N],mde[N],mv[N],de[N],ans=-inf;
    bool use[N];
    struct node 
    {
    	long long x,w,def;//atk==x?????def==x 
    	bool operator <(const node &t)const{return x<t.x;}
    }a[N],b[N],c[N];
    struct node3
    {
    	long long sum,maxn,add;
    }t[N*4];
    long long max(long long x,long long y)
    {
    	if(x>y)
    		return x;
    	return y;
    }
    void built(int p,int l,int r)
    {
    	t[p].add=0;
    	if(l==r)
    	{
    		t[p].maxn=-a[l].w;
    		//t[p].sum=-b[l].w;
    		return ;
    	}
    	int mid=(l+r)/2;
    	built(p*2,l,mid);
    	built(p*2+1,mid+1,r);
    	t[p].maxn=max(t[p*2].maxn,t[p*2+1].maxn);
    	//t[p].sum=t[p*2].sum+t[p*2+1].sum;
    }
    void push_tag(int p,int l,int r)
    {
    	if(t[p].add)
    	{
    		t[p*2].add+=t[p].add;
    		t[p*2+1].add+=t[p].add;
    		t[p*2].maxn+=t[p].add;
    		t[p*2+1].maxn+=t[p].add;
    		t[p].add=0;
    	}
    	return ;
    }
    void push_down(int p)
    {
    	t[p].maxn=max(t[p*2].maxn,t[p*2+1].maxn);
    }
    void up(int p,int qx,int zx,int gl,int gr,int k) 
    {
    	if(qx>=gl&&zx<=gr)
    	{
    		t[p].add+=k;
    		t[p].maxn+=k;
    		return ;
    	}
    	int mid=(qx+zx)/2;
    	push_tag(p,qx,zx);
    	if(gl<=mid)
    		up(p*2,qx,mid,gl,gr,k);
    	if(gr>mid)
    		up(p*2+1,mid+1,zx,gl,gr,k);
    	push_down(p);
    	return ;
    }
     
    long long askmaxn(int p,int qx,int zx,int gl,int gr)
    {
    	if(qx>=gl&&zx<=gr)
    	{
    		return t[p].maxn;
    	}
    	int mid=(qx+zx)/2;
    	long long ans=-inf;
    	if(gl<=mid)	
    		ans=max(ans,askmaxn(p*2,qx,mid,gl,gr));
    	if(gr>mid)
    		ans=max(ans,askmaxn(p*2+1,mid+1,zx,gl,gr));
    	return ans;
    }
    int main()
    {
    	scanf("%d %d %d",&n,&m,&p);
    	for(int i=1;i<=n;i++)
    		scanf("%lld %lld",&a[i].x,&a[i].w);
    	for(int i=1;i<=m;i++)
    		scanf("%lld %lld",&b[i].x,&b[i].w);
    	for(int i=1;i<=p;i++)
    		scanf("%lld %lld %lld",&c[i].def,&c[i].x,&c[i].w);
    	sort(a+1,a+n+1);
    	sort(b+1,b+m+1);
    	sort(c+1,c+p+1);
    	for(int i=1;i<=p;i++)
    	{
    		mat[i]=c[i].x;
    		mv[i]=c[i].w;
    		mde[i]=c[i].def;
    	}
    	for(int i=1;i<=n;i++)
    		de[i]=a[i].x; 
    	built(1,1,n);
    	for(int i=1;i<=m;i++)
    	{
    		if(b[i].x>mat[p])
    			pos2=p;
    		else
    			pos2=lower_bound(mat+1,mat+p+1,b[i].x)-mat-1;
    		for(int j=pos1+1;j<=pos2;j++)
    		{
    			//printf("#@$%d %d ",de[n],mde[j]);
    			if(de[n]<=mde[j])
    				continue;
    			else
    				pos3=upper_bound(de+1,de+n+1,mde[j])-de;
    			//printf("pos3=%d ", pos3);
    			up(1,1,n,pos3,n,mv[j]);
    			pos1=pos2;
    		}
    		ans=max(ans,askmaxn(1,1,n,1,n)-b[i].w);
    		//printf("%lld ",askmaxn(1,1,n,1,n));
    	}
    	printf("%lld",ans);
    	return 0;
    } 

    E题已经让我憔悴不堪,F题有生之年吧 

  • 相关阅读:
    dcokee 安装 nginx
    docker 私有仓库
    docker下的images 保存和导出
    mybatis-puls 字段为null时候的更新问题
    MyBatis-Plus的一些问题
    60万数据的表添加索引查询的速度
    Velocity 模板引擎的应用
    什么是javabean及其用法
    java中this和super关键字的使用
    Windows-AutoHotkey-常用代码保存
  • 原文地址:https://www.cnblogs.com/cherrypill/p/12399072.html
Copyright © 2011-2022 走看看