ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CodeTON Round 2(持续更新中)

2022-08-02 12:00:15  阅读:206  来源: 互联网

标签:const int CodeTON 更新 RI freopen include Round define


Preface

现在菜的真实啊……比赛的时候打的慢就算了还天天写假算法,可怜……

ABCD用了1h,然后E以为不会爆long long(主要我的做法很奇怪很脑残),当场去世


A. Two 0-1 Sequences

签到题,首先我们发现一个先决条件:a的后\(m-1\)位必须和b的后\(m-1\)位相等,因为修改影响不到后面

我们发现操作的本质就是在a的前\(n-m+1\)位中任选一个保留下来,因此只需要看这些数中有没有和b的首位相同的即可

#include<cstdio>
#include<iostream>
#include<algorithm>
#define RI register int
#define CI const int&
using namespace std;
const int N=55;
int t,n,m; char a[N],b[N];
int main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	for (scanf("%d",&t);t;--t)
	{
		RI i,pos=0; scanf("%d%d%s%s",&n,&m,a+1,b+1);
		for (i=1;i<=m;++i) if (a[n-i+1]!=b[m-i+1]) { pos=i; break; }
		if (!pos) { puts("YES"); continue; }
		if (pos!=m) { puts("NO"); continue; }
		bool flag=0; for (i=1;i<=n-m+1;++i)
		if (a[i]==b[1]) { flag=1; break; }
		puts(flag?"YES":"NO");
	}
	return 0;
}

B. Luke is a Foodie

不难发现对于一个区间\([l,r]\),它们可以被同一个数一起拿走的充要条件是\(\max_{l\le i\le r} a_i-\min_{l\le i\le r} a_i\le 2x\)

由于我们必须按顺序取走每一个数,因此直接从左往右贪心,每次取走能取的最大的区间即可

#include<cstdio>
#include<iostream>
#include<algorithm>
#define RI register int
#define CI const int&
using namespace std;
const int INF=1e9;
int t,n,m,x,mi,mx,ans;
int main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	for (scanf("%d",&t);t;--t)
	{
		RI i; for (scanf("%d%d",&n,&m),mi=INF,ans=mx=0,i=1;i<=n;++i)
		{
			scanf("%d",&x); mi=min(mi,x); mx=max(mx,x);
			if (mx-mi>2*m) ++ans,mx=mi=x;
		}
		printf("%d\n",ans);
	}
	return 0;
}

C. Virus

首先把所有被病毒分割开的区间算出来,如果不考虑堵上感染的话每天这些区间长度就会减\(2\)

考虑堵上的顺序,一开始以为随便怎么堵对答案都没影响,因为每次总减去的数目不变

后来发现对于长度为1和2的区间,即使堵住了也没法拯救更多的了,因此我们贪心地从长的区间开始堵即可

#include<cstdio>
#include<iostream>
#include<algorithm>
#define RI register int
#define CI const int&
using namespace std;
const int N=100005;
int t,n,m,a[N],b[N],cnt,ans;
int main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	for (scanf("%d",&t);t;--t)
	{
		RI i; for (scanf("%d%d",&n,&m),i=1;i<=m;++i) scanf("%d",&a[i]);
		for (sort(a+1,a+m+1),i=1;i<m;++i) b[i]=a[i+1]-a[i]-1;
		b[m]=n-a[m]+a[1]-1; sort(b+1,b+m+1);
		for (ans=cnt=0,i=m;i;--i) if (b[i]-cnt*2>0)
		{
			if (b[i]-cnt*2<=2) ++cnt,++ans; else ans+=b[i]-cnt*2-1,cnt+=2;
		} else break;
		printf("%d\n",n-ans);
	}
	return 0;
}

D. Magical Array

STO YKH ORZ

不难发现这个两种操作都很像差分,因此我们把\(c_i\)的前缀和数组\(s_i\)求出

然后我们发现操作1对\(\sum_{i=1}^m s_i\)的大小是没影响的,而每一次操作2会让\(\sum_{i=1}^m s_i\)的值减1

发现这个性质后就很简单了

#include<cstdio>
#include<iostream>
#include<algorithm>
#define int long long
#define RI register int
#define CI const int&
using namespace std;
const int N=300005;
int t,n,m,x,pre,f[N];
signed main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	for (scanf("%lld",&t);t;--t)
	{
		RI i,j,p,c; for (scanf("%lld%lld",&n,&m),i=1;i<=n;++i)
		for (pre=f[i]=0,j=1;j<=m;++j) scanf("%lld",&x),pre+=x,f[i]+=pre;
		for (i=1;i<n;++i) if (f[i]!=f[i+1]) { p=i; break; }
		for (c=0,i=1;i<=n;++i) if (f[i]==f[p]) ++c;
		if (c==n-1) printf("%lld %lld\n",p+1,f[p]-f[p+1]); else printf("%lld %lld\n",p,f[p+1]-f[p]);
	}
	return 0;
}

E. Count Seconds

我的做法很蠢权当娱乐的说

首先数据范围很小我们考虑暴力,朴素的直接枚举时间的方法肯定不可行

因此我们想到每次找出\(a_i\)不为0且最小的入度为0的点\(p\),然后让时间经过\(a_p\),这样这个点就被永久剔除了

然后写完就发现会出现前面的点值不为0而后面的点值为0导致的堵塞行为(其实就是样例2)

但是YKHdalao敏锐地发现了在经过\(n-1\)次操作后,必然会形成如果点\(i\)满足\(a_i\ne 0\),那么它能到达的所有点\(j\)一定满足\(a_j\ne 0\)的局面,就可以用上面的方法做了

然后我就开始写,随后又发现取模之后我们没法正确的找出最小值了

但是由于我们这里只需要能比较数据的大小关系,不妨把一个数表示成\(A\times 998244353+B(B<998244353)\)的形式

因为\(A\)不参与答案计算,因此直接用long double暴力存下\(A\)大致量级即可完成比较操作

复杂度\(O(n^2)\)

#include<cstdio>
#include<iostream>
#include<vector>
#include<algorithm>
#define RI register int
#define CI const int&
using namespace std;
const int N=1005,mod=998244353;
typedef vector <int>:: iterator VI;
int t,n,m,x,y,in[N],a[N],b[N],vis[N],tar,timm; vector <int> v[N];
struct data
{
	long double p; int r;
	friend inline bool operator < (const data& A,const data& B)
	{
		if (A.p<B.p) return 1; if (A.p>B.p) return 0; return A.r<B.r;
	}
	friend inline data operator + (const data& A,const data& B)
	{
		data C; if (A.r+B.r>=mod) C=(data){A.p+B.p+1,A.r+B.r-mod};
		else C=(data){A.p+B.p,A.r+B.r}; return C;
	}
	friend inline data operator - (const data& A,const data& B)
	{
		data C; if (A.r-B.r<0) C=(data){A.p-B.p-1,A.r-B.r+mod};
		else C=(data){A.p-B.p,A.r-B.r}; return C;
	}
	friend inline data operator * (CI x,const data& B)
	{
		int P=1LL*x*B.r/mod,R=1LL*x*B.r%mod; return (data){x*B.p+P,R};
	}
}c[N],tim;
inline bool check(void)
{
	for (RI i=1;i<=n;++i) if (a[i]) return 1; return 0;
}
inline int add(CI x,CI y)
{
	return x+y>=mod?x+y-mod:x+y;
}
int main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	for (scanf("%d",&t);t;--t)
	{
		RI i,j; for (scanf("%d%d",&n,&m),i=1;i<=n;++i)
		scanf("%d",&a[i]),v[i].clear(),in[i]=vis[i]=0;
		for (i=1;i<=m;++i) scanf("%d%d",&x,&y),++in[y],v[x].push_back(y);
		for (i=1;i<=n;++i) if (!v[i].size()) tar=i; timm=0;
		for (;timm<=n&&check();++timm)
		{
			for (i=1;i<=n;++i) b[i]=0;
			for (i=1;i<=n;++i) if (a[i])
			{
				--b[i]; for (VI it=v[i].begin();it!=v[i].end();++it) ++b[*it];
			}
			for (i=1;i<=n;++i) a[i]+=b[i];
		}
		if (!check()) { printf("%d\n",timm); continue; }
		for (i=1;i<=n;++i) c[i]=(data){0,a[i]}; tim=(data){0,timm};
		for (;;)
		{
			if (!in[tar]) { printf("%d\n",add(c[tar].r,tim.r)); break; }
			int p=0; data mi; for (i=1;i<=n;++i)
			if (!in[i]&&!vis[i]) if (!p||c[i]<mi) mi=c[i],p=i;
			for (i=1;i<=n;++i) c[i]=c[i]-mi+(in[i]*mi); tim=tim+mi; vis[p]=1;
			for (VI it=v[p].begin();it!=v[p].end();++it) --in[*it];
		}
	}
	return 0;
}

PS:看了sol发现我就是个睿智,连拓扑排序都想不到

直接把拓扑序求出来之后按序把\(a_i\)加到后面相连的点即可,不过仍然需要前面的\(n-1\)次爆枚来保证没有0点堵塞


标签:const,int,CodeTON,更新,RI,freopen,include,Round,define
来源: https://www.cnblogs.com/cjjsb/p/16543315.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有