首页 > 其他分享 >Hello 2023(持续更新)

Hello 2023(持续更新)

时间:2023-01-04 22:12:10浏览次数:52  
标签:const int 更新 RI define 2023 include Hello out

Preface

2023的First Round的说,虽然犯了很多脑抽错误但幸好还是堪堪上了点分

比赛时写出了ABCD,E结束前3min刚写完结果挂PT6了,今天稍微改了下就过了

嘛不管怎样还是跌跌撞撞回到1800+了,可以再次开始冲击紫名了


A. Hall of Fame

比赛的时候不知道为什么脑抽了想复杂了,然后10min的时候才堪堪做掉

我的思路就是设第一个出现的R的下标为\(x\),最后一个出现的L的下标为\(y\),若\(x<y\)则有解

首先判断掉不用交换就合法的情况,然后考虑交换的只可能是相邻的LR,在交换的时候维护下新的\(x,y\)来判断即可

#include<cstdio>
#include<iostream>
#define RI register int
#define CI const int&
using namespace std;
const int N=100005;
int t,n,L1,R1; char s[N];
int main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	for (scanf("%d",&t);t;--t)
	{
		RI i; scanf("%d%s",&n,s+1); L1=0; R1=n+1;
		for (i=1;i<=n;++i) if (s[i]=='R')
		{
			if (R1==n+1) R1=i; else break;
		}
		for (i=n;i>=1;--i) if (s[i]=='L')
		{
			if (!L1) L1=i; else break;
		}
		if (R1<L1) { puts("0"); continue; }
		bool flag=0; for (i=1;i<n&&!flag;++i) if (s[i]!=s[i+1])
		{
			if (s[i]=='L')
			{
				int LL=L1,RR=R1;
				if (i==LL) ++LL; if (i+1==RR) --RR;
				if (RR<LL) { printf("%d\n",i); flag=1; }
			} 
		}
		if (!flag) puts("-1");
	}
	return 0;
}

B. MKnez's ConstructiveForces Task

首先一眼偶数随便构造,直接\(1,-1,1,-1,\cdots,1,-1\)这样即可

然后奇数第一眼以为是无解的,后面细想了一下还是可以构造\(n>3\)的情况的

首先不难发现所有奇数位置上的数都要相同,且所有偶数位置上的数也要相同,否则不合法

设\(\sum_{i=1}^n s_i=t\),我们把所有的\(n-1\)对相邻的数相加,则可以列出式子\((n-1)t=2t-(s_1+s_n)\)

因此\(s_1=s_n=\frac{-(n-3)t}{2}\),然后我们不妨设\(t=-1\)即可得到一种构造方案

比如\(n=5\)时有

1 -2 1 -2 1

\(n=7\)时有

2 -3 2 -3 2 -3 2

依此类推即可

#include<cstdio>
#include<iostream>
#define RI register int
#define CI const int&
using namespace std;
const int N=1005;
int t,n;
int main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	for (scanf("%d",&t);t;--t)
	{
		RI i; if (scanf("%d",&n),n==3) { puts("NO"); continue; }
		if (puts("YES"),n&1)
		{
			int x=(n-3)/2;
			for (i=1;i<=n;++i) printf("%d%c",i&1?x:-(x+1)," \n"[i==n]);
		} else
		{
			for (i=1;i<=n;++i) printf("%d%c",i&1?1:-1," \n"[i==n]);
		}
	}
	return 0;
}

C. Least Prefix Sum

我真是傻逼竟然会认为直接贪心是对的,WA了两发不说还浪费好多时间,真想给自己两个大耳光子

首先我们令\(pfx_i=\sum_{j=1}^i a_j\),把\(pfx_k\ge pfx_m\)的条件转化一下:

  • 若\(k<m\),则\(pfx_k\ge pfx_m\Leftrightarrow \sum_{i=k+1}^m a_i\le 0\)
  • 若\(k>m\),则\(pfx_k\ge pfx_m\Leftrightarrow \sum_{i=m+1}^k a_i\ge 0\)

因此我们分别处理两边的情况,刚开始我naive地认为在所有不合法的地方进行反转操作即可

后来稍加思索造了个数据把自己卡了

5 1
0 10 -9 -8 -10

遂发现这是个最简单的带悔贪心的题,我们把所有没反转过的数扔到堆里,在未来选择反悔选它的时候贡献就是\(-2\times a_i\)

每次需要反转的时候找一个最优的出来即可,总复杂度\(O(n\log n)\)

#include<cstdio>
#include<iostream>
#include<queue>
#define RI register int
#define CI const int&
using namespace std;
const int N=200005;
int t,n,m,a[N],ans; priority_queue <int> hp;
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<=n;++i) scanf("%d",&a[i]);
		while (!hp.empty()) hp.pop();
		long long cur=0; for (ans=0,i=m;i>=2;--i)
		if (hp.push(2*a[i]),cur+a[i]>0)
		++ans,cur+=-hp.top()+a[i],hp.pop(); else cur+=a[i];
		while (!hp.empty()) hp.pop();
		for (cur=0,i=m+1;i<=n;++i)
		if (hp.push(-2*a[i]),cur+a[i]<0)
		++ans,cur+=hp.top()+a[i],hp.pop(); else cur+=a[i];
		printf("%d\n",ans);
	}
	return 0;
}

D. Boris and His Amazing Haircut

这题确实很naive了,随便想想都知道怎么做,还好C过完之后心态没爆炸很稳地一遍写过,不然铁掉分

首先考虑特判掉\(a_i<b_i\)的情况,然后我们发现我们可以按从小到大的顺序考虑所有\(b_i\)

即我们先把所有数离散化,然后枚举一个在\(b_i\)中未被处理掉的最小的数\(t\)

考虑找出所有\(b_i=t\and a_i\ne t\)的下标序列\(s_1,s_2,\cdots,s_m\)

刚开始naive地认为只要找到\(s_1,s_2,\cdots,s_m\)一共可由多少个区间覆盖,把这个值和\(x_i\)中\(t\)的个数做比较即可

但是后来发现所有之前已经被处理掉的位置会起到一个联通两端的作用

比如我们要把3 3 3变成2 1 2,在用一把值为1的锥子后我们把下标为\(2\)的位置处理掉了,这样位置\(1\)和位置\(3\)其实就相当于可以放在一起处理了,我们再用一把值为2的锥子把\([1,3]\)都推了即可

因此我们再用一个双向列表来维护下每个数左右第一个没被处理掉的位置是什么即可

总体实现起来由于要排序,因此复杂度为\(O(n\log n)\)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
#define RI register int
#define CI const int&
using namespace std;
const int N=800005;
int t,n,m,a[N],b[N],rst[N],cnt,L[N],R[N],x[N],num[N],tp[N],tot; vector <int> pos[N];
inline void remove(CI x)
{
	int pre=L[x],nxt=R[x]; R[pre]=nxt; L[nxt]=pre;
}
int main()
{
	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
	for (scanf("%d",&t);t;--t)
	{
		RI i,j; for (scanf("%d",&n),cnt=0,i=1;i<=n;++i) scanf("%d",&a[i]),rst[++cnt]=a[i];
		for (i=1;i<=n;++i) scanf("%d",&b[i]),rst[++cnt]=b[i];
		for (scanf("%d",&m),i=1;i<=m;++i) scanf("%d",&x[i]),rst[++cnt]=x[i];
		bool flag=1; for (i=1;i<=n&&flag;++i) if (a[i]<b[i]) flag=0;
		if (!flag) { puts("NO"); continue; }
		sort(rst+1,rst+cnt+1); cnt=unique(rst+1,rst+cnt+1)-rst-1;
		for (i=1;i<=n;++i) a[i]=lower_bound(rst+1,rst+cnt+1,a[i])-rst;
		for (i=1;i<=n;++i) b[i]=lower_bound(rst+1,rst+cnt+1,b[i])-rst;
		for (i=1;i<=cnt;++i) pos[i].clear(),num[i]=0;
		for (i=1;i<=m;++i) ++num[x[i]=lower_bound(rst+1,rst+cnt+1,x[i])-rst];
		for (i=1;i<=n;++i) L[i]=i-1,R[i]=i+1,pos[b[i]].push_back(i);
		for (i=1;i<=cnt&&flag;++i) if (pos[i].size())
		{
			tot=0; for (int t:pos[i]) if (a[t]==b[t]) remove(t); else tp[++tot]=t;
			if (!tot) continue;	int cur=1; for (j=1;j<tot;++j)
			if (R[tp[j]]!=tp[j+1]) ++cur;
			if (cur>num[i]) flag=0; for (j=1;j<=tot;++j) remove(tp[j]);
		}
		puts(flag?"YES":"NO");
	}
	return 0;
}

E. Anya's Simultaneous Exhibition

比赛的时候连蒙带猜基本把方法搞出来了,结果写的时候一个下标搞错了多了\(1\),可惜差点完成2min绝杀

考虑若\(x\)能战胜\(y\),我们就连一条\(x\to y\)的有向边,首先我们考虑用\(n\)次操作问出每个点的出度\(out_i\)

然后我们不难发现出度最多的点\(x\)一定可以获胜,考虑用反证法

因为一定会存在至少一个点获胜,而这个点不是\(x\),我们不妨将其设为\(y\),且满足\(out_x\ge out_y\)

那么我们不难推出\(x,y\)之间的边一定是\(y\to x\),否则\(x\)可以让\(y\)打败其它点后再打败他而获胜

依此类推对于所有\(x\)能打赢的点\(z\),\(y\)也必须要打赢\(z\),否则\(x\)可以让\(y\)打败其它点后再用\(z\)打败\(y\),再自己打败\(z\)获胜

因此我们发现所有\(x\)出度的点,也必是\(y\)的出度,并且由于\(y\to x\)这条边,我们可以推出\(out_x<out_y\)

这与\(out_x\)是出度最大的点矛盾,因此假设不成立

因此由这个思路我们不难想到一种利用归纳法的方法来判断每个点是否能获胜

我们把所有点按出度从大到小排序,假设我们已经确定了点\(1,2,\cdots,k\)可以获胜

如果点\(k+1,k+2,\cdots n\)到前\(k\)个点都没边,则最后的答案就是前\(k\)个点

否则我们可以找出后面的点中第一个到前\(k\)个点有边的点\(t\),则这个点必然也是可以获胜的

然后我们令\(k=t\),继续扩展可以获胜的点的集合的边界即可,不难发现这样操作最多只要再进行\(n-1\)次询问即可

#include<cstdio>
#include<iostream>
#include<algorithm>
#define RI register int
#define CI const int&
using namespace std;
const int N=255;
struct element
{
	int out,id;
	friend inline bool operator < (const element& A,const element& B)
	{
		return A.out>B.out;
	}
}a[N]; int n,ans[N],mark[N],lim;
int main()
{
	RI i,j; for (scanf("%d",&n),i=1;i<=n;++i)
	{
		for (printf("? %d ",i),j=1;j<=n;++j)
		printf("%c",i!=j?'1':'0'); printf("\n");
		fflush(stdout); scanf("%d",&a[i].out); a[i].id=i;
	}
	for (lim=1,sort(a+1,a+n+1),i=2;i<=n;++i)
	{
		for (j=1;j<=n;++j) mark[j]=0;
		for (j=1;j<=lim;++j) mark[a[j].id]=1;
		for (printf("? %d ",a[i].id),j=1;j<=n;++j)
		printf("%c",mark[j]?'1':'0'); printf("\n");
		fflush(stdout); int tp; scanf("%d",&tp);
		if (tp) lim=i;
	}
	for (i=1;i<=lim;++i) ans[a[i].id]=1;
	for (printf("! "),i=1;i<=n;++i)
	printf("%c",ans[i]?'1':'0'); printf("\n");
	return fflush(stdout),0;
}

标签:const,int,更新,RI,define,2023,include,Hello,out
From: https://www.cnblogs.com/cjjsb/p/17026133.html

相关文章

  • 2023,1 做题笔记
    Hello2023!【CF1025G】CompanyAcquisitions考虑用势能函数去描述一个状态\(A=\{a_1,a_2,...,a_n\}\),令\(w(A)=\sum_{i=1}^nf(a_i)\),其中\(f(a_i)\)是一个关于\(a_......
  • Hello 2023 D.Boris and His Amazing Haircut
    Problem-D-Codeforces题意:给两个长度为n的数组a,b,再给一个数组长度为m的数组x,表示m次操作每次操作把选择一个区间把a[l~r]中大于x[i]的变为x[j],否则不变问能否在m次......
  • 题解 校内考20230104 T2 旗木双翼
    题目描述菲菲和牛牛在一块\(n\)行\(m\)列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手。棋局开始时,棋盘上没有任何棋子,两人轮流在格子上落子,直到填满棋盘时结束。落子......
  • C语言银行业务模拟系统[2023-01-04]
    C语言银行业务模拟系统[2023-01-04]银行业务模拟系统系统要求使用C语言实现一个银行业务模拟程序,实现存取款等基本业务的模拟。选题者需要首先进行需求调研,了解银行的主......
  • 2023 重新开始
    误入网络安全这个行业有三年多了,这三年主要工作就是等保里面的渗透,基本项目都在重复劳动,三年下来跟刚入行的时候水平差不多,没学到什么技术。浑浑噩噩度过了三年,自......
  • C/C++数学口算比赛系统[2023-01-04]
    C/C++数学口算比赛系统[2023-01-04]题目三数学口算比赛系统设计要求:适用于小学生数学口算比赛的系统。比赛题型分为两种:“四则简单运算”和“四则混合运算”,计算机......
  • C/C++图书管理系统[2023-01-04]
    C/C++图书管理系统[2023-01-04]17、图书管理系统主要包括管理图书的库存信息、每一本书的借阅信息以及每一个人的借书信息。每一种图书的库存信息包括编号、书名、作者、......
  • C语言学生成绩管理系统[2023-01-04]
    C语言学生成绩管理系统[2023-01-04]设计题目:《学生成绩管理系统》设计目的利用所学的三种程序基本结构以及数组、用户自定义函数进行一个简单管理系统的设计,进一步理......
  • C语言车票管理系统[2023-01-04]
    C语言车票管理系统[2023-01-04]一车站每天有n个发车班次,每个班次都有一班次号(1、2、3…n),固定的发车时间,固定的路线(起始站、终点站),大致的行车时间,固定的额定载客量。如......
  • Metagenome宏基因组 质控 过滤 比对 去除宿主 2023.01.01-202301.02
    质控过滤比对去除宿主#云硬盘挂在100Gvirtio-disk-bxgzkldx/dev/disk/by-id/virtio-disk-bxgzkldx/dataext4defaults00#uniport数据库下载wgethttps://ftp.unip......