AtCoderAtCoder Grand Contest 041 解题报告(开坑之时已至,目前只有$A,B,C$)

Posted chenxiaoran666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AtCoderAtCoder Grand Contest 041 解题报告(开坑之时已至,目前只有$A,B,C$)相关的知识,希望对你有一定的参考价值。

点此进入比赛

这里只是开个坑,然后把已经写掉的(A,B,C)题解先水一水,剩下的题目打算到时候再做吧。

(A):Table Tennis Training(点此看题面

大致题意:(n)个位置,一开始一对好朋友分别在(a,b)两个位置。每单位时间,二人可分别选择向左或向右走(1)个位置(若超出范围则保持不动),求二人至少要多少时间相遇。

不妨设(a<b),则可以进行如下分类讨论。

(b-a)为偶数

显然,此时二人只要向着对方走,只需(frac{b-a}2)的时间即可相遇。

(b-a)为奇数

显然,此时必然是一个人走到(1)(n),在那里等一回合使得二人间距离为偶数,然后再走到一起。

而且必然是(a)走到(1)或者(b)走到(n),因此我们再分类讨论:

  • (a)走到(1)(a)走到(1)并等待一回合共需要(a)的时间,此时(b)走到了(b-a),因此还需(frac{b-a-1}2)的时间。总时间为(a+frac{b-a-1}2)
  • (b)走到(n)(b)走到(n)并等待一回合共需要(n-b+1)的时间,此时(a)走到了(n-b+1+a),因此还需(frac{b-a-1}2)的时间。总时间为((n-b+1)+frac{b-a+1}2)

综上所述,最短时间应为(min(a,n-b+1)+frac{b-a+1}2)

提交记录

神奇地(CE)了两发。。。(似乎是选错了语言,好像不能选Clang?)

然后一发就过了。

代码

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define LL long long
#define swap(x,y) (x^=y^=x^=y)
#define min(x,y) ((x)<(y)?(x):(y))
using namespace std;
LL n,a,b;
int main()
{
	scanf("%lld%lld%lld",&n,&a,&b);if(a>b&&swap(a,b),(a&1)==(b&1)) return printf("%lld",b-a>>1),0;//使a<b;处理偶数情况
	return printf("%lld",(b-a-1>>1)+min(a,n-b+1)),0;//处理奇数情况
}

(B):Voting Judges(点此看题面

大致题意:(n)个数,你需要进行(m)次操作,每次选择恰好(v)个数各加(1)。求有多少个数在(m)次操作后可能成为前(p)大的数。

可二分性≠要用二分做

显然这道题是具有可二分性的,因为如果一个数可以,那么比它大的数一定都可以。

但我们一定要用二分吗?事实上,我们直接枚举判断,也可以做到(O(n))

因此,具有可二分性的题目,不一定就要用二分做。

如何判断

考虑将所有数从大到小排序,设为(a_{1sim n}),并令(s_{1sim n})为其前缀和。

假设我们当前判断(a_i)是否可能成为前(p)大的数,那么按照贪心的思想,我们只要让它刚好卡在第(p)个就可以了。

因此,我们可以把第(i)个数、最大的(p-1)个数(因为这(p-1)个数是无须超越的)、比(i)小的(n-i+1)个数(因为这些数怎么加都超不过第(i)个数)全都加上(m)

则还剩下需要加的(1)的个数为:

[max(v-p-(n-i),0) imes m ]

我们考虑求出把第(psim i-1)个数全都刚好加到(a_i+m),如果加不到或恰好加满说明当前答案可行,若有(1)剩余说明不可行。

那么需要多少个(1)呢?这时候前面记下的前缀和就派上用场了,需要的(1)的个数就是:

[(i-p) imes (a_i+m)-(s_{i-1}-s_{p-1}) ]

似乎我们只要比较这个式子与前面式子的大小关系就能得出答案了,但这其实是有瑕疵的。

为什么呢?因为假如你有一个数原本就大于(a_i+m),难道你还能给它负数个(1),让它变小吗?

所以,我们要先判一下(a_i+m)是否大于等于(a_p),然后再进行上述判断。(闪指导就被这个坑了)

提交记录

第一发交完等待评测的时候,突然发现有个地方漏开(long long)了。

于是第一发果不其然(WA)了,开了(long long)重交了一发才过。

代码

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
#define LL long long
using namespace std;
int n,m,v,p,a[N+5];LL s[N+5];
I bool cmp(CI x,CI y) {return x>y;}//从大到小排序
int main()
{
	RI i;for(scanf("%d%d%d%d",&n,&m,&v,&p),i=1;i<=n;++i) scanf("%d",a+i);
	for(sort(a+1,a+n+1,cmp),i=1;i<=n;++i) s[i]=s[i-1]+a[i];//排序后求前缀和
	for(i=n;i>p;--i) if(a[i]+m>=a[p])//枚举答案,首先要使得加上m后大于等于第p个数
		if(1LL*max(v-p-(n-i),0)*m<=1LL*(a[i]+m)*(i-p)-(s[i-1]-s[p-1])) break;//用1去填平中间的坑
	return printf("%d",i),0;//输出答案(若始终没break则最后i恰好等于p)
}

(C):Domino Quality(点此看题面

大致题意: 有一张(n imes n)的网格图,你要摆上至少一个(1 imes 2)的骨牌,使得各行各列覆盖其至少一格的骨牌个数皆相等。

注意:接下来开始的三部分都只是我的思路历程(勿喷),此题终题解只需看总结部分即可。

手玩一小时

这种构造题一般套路想想都是手玩->发现规律->切掉,怀着这样的想法,我就开始了暗无天日的手玩。。。

于是,大约一小时过去了,弱小的我和强大的闪指导依旧只画出了(n=3,4,5)的解。

而且,没有任何规律。。。

题解的辅助

没办法,只好去找了篇题解,看了看最终的规律似乎是:

  • 对于(n=3,5,7),直接打表。
  • 对于(n)为偶数,若(n=4)则打表,否则规律显然。
  • 对于(n)为奇数,补一个(n=5)的答案转化为(n)为偶数。

于是我们从中得到了几点启发:

  • 难怪我们没有找到任何规律,因为我们求出的这几个答案都是特殊情况。。。
  • 我们还需要手玩出(n=7)并发现(n)为偶数的规律,再去考虑怎么补上(n=5)的答案把奇数变成偶数,这又将是一个浩大的工程。

画去画去就困了,先睡个觉,明天再接着画。

自习课加成

果然,正如闪指导所言,在班里就能智商++,自习课更是有着极为优秀的加成。

第二天起来到班里,来机房前就无聊乱画(说起来今明两天是月考,因为停课逃掉了),结果突然就把(n)为偶数情况的规律画出来了?!

此时极为亢奋的我再接再厉,不到一分钟又画出了(n=7)?!

(顺便说一下,过于亢奋的我刚画完就兴冲冲地奔向了机房,到了之后发现画了图的草稿纸没带,结果凭借残余的记忆还又用了五六分钟才重新画出(n=7)的解。由此再次验证了闪指导的话的正确性,果然闪指导是我们的红太阳,他说的话都是真理!)

总结

好了,上面那一堆都是废话,接下来才是正经的结论。

  • 对于(n=3,5,7),直接打表。(可见代码)

  • 对于(n)为偶数,我的确是自己推出了一个统一的规律,但感觉把(n)分类为模(6)(0,2,4)三种情况似乎更好理解、说明,也更好码(码量虽然大了点,但实际只是多按了几个(Ctrl C+Ctrl V)):

    (n\\%6=0)如图所示:(由于我比较懒,图被吞了,直接用题目中的表示方法吧)

    x.aa......z.
    x.bb......z.
    y.cc......y.
    y...aa....y.
    z...bb....x.
    z...cc....x.
    .x....aa...z
    .x....bb...z
    .y....cc...y
    .y......aa.y
    .z......bb.x
    .z......cc.x
    

    我想图画出来后这规律应该就比较显然了吧。。。

    (n\\%6=2)如图所示

    x.aa.......p..
    x.bb.......p..
    y..cc.......z.
    y...aa......z.
    z...bb......y.
    z....cc.....y.
    .x....aa....x.
    .x....bb....x.
    .y.....cc....z
    .y......aa...z
    .z......bb...y
    .z.......cc..y
    ..p.......aa.x
    ..p.......bb.x
    

    (n\\%6=0)很像,不是吗?事实上,仔细观察就发现仅仅是把所有"cc"右移了一格(可理解为"pp"的存在占据了"cc"原本的位置)。

    (n\\%6=4)如图所示

    x.aa.........q..
    x..bb........q..
    y..cc........p..
    y...aa.......p..
    z....bb.......z.
    z....cc.......z.
    .x....aa......y.
    .x.....bb.....y.
    .y.....cc.....x.
    .y......aa....x.
    .z.......bb....z
    .z.......cc....z
    ..p.......aa...y
    ..p........bb..y
    ..q........cc..x
    ..q.........aa.x
    

    看完前两种情况就很好明白了,"pp"和"qq"占据了"bb"和"cc"原本的位置,使得"bb"和"cc"需要右移一格。

  • 对于(n)为奇数,我们需要这样画:

    **********.....
    **********.....
    **********.....
    **********.....
    **********.....
    **********.....
    **********.....
    **********.....
    **********.....
    **********.....
    ..........abba.
    ..........a..ab
    ..........bba.b
    ..........a.acc
    ..........abbaa
    

    其中"*"构成的矩阵表示(n-5)的答案,右下角为(5)的答案。

大体上就是这样了,然后就是模拟模拟模拟。

提交记录

(RE)???仔细看了一遍代码,然后发现智障地写了这样一句:

return puts("-1");

(WA)???而且只(WA)一个点???

不断思索有什么单个数据是特殊的,最后发现挂在了(9)上((5+4)),(9)中的(4)也是需要特判的,而我原本是把(4)单独拉出来特判的。所以只好又把(4)的情况放回了偶数大家庭。。。

然后终于过了。

代码

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 1000
using namespace std;
int n,a[N+5];char s[N+5][N+5];
char s3[4][4]={"","aab","b.b","baa"};
char s5[6][6]={"","abba.","a..ab","bba.b","a.acc","abbaa"};
char s7[8][8]={"","aabbaa.","b..a..a","b..a..a","...baab","...bccb","abb...a","acc...a"};
char s4[5][5]={"","aaba","ccba","abcc","abaa"};
I void Draw(CI n)//模拟看起来很长,实际上仔细看下就发现三部分几乎一样,只有小变动而已(实际上我本来就基本上是复制粘贴的)
{
	RI i,j;if(n==4)//特判n=4
	{
		for(i=1;i<=4;++i) for(j=1;j<=4;++j) s[i][j]=s4[i][j-1];return;
	}
	if(n%6==0)
	{
		for(i=1;i<=n/6;++i)
			s[6*i-5][i]=s[6*i-4][i]=s[n-6*i+6][n-i+1]=s[n-6*i+5][n-i+1]=‘x‘,
			s[6*i-3][i]=s[6*i-2][i]=s[n-6*i+4][n-i+1]=s[n-6*i+3][n-i+1]=‘y‘,
			s[6*i-1][i]=s[6*i][i]=s[n-6*i+2][n-i+1]=s[n-6*i+1][n-i+1]=‘z‘;
		for(i=1;i<=n/3;++i)
			s[3*i-2][n/6+2*i-1]=s[3*i-2][n/6+2*i]=‘a‘,
			s[3*i-1][n/6+2*i-1]=s[3*i-1][n/6+2*i]=‘b‘,
			s[3*i][n/6+2*i-1]=s[3*i][n/6+2*i]=‘c‘;
	}
	if(n%6==2)
	{
		for(i=1;i<=n/6;++i)
			s[6*i-5][i]=s[6*i-4][i]=s[n-6*i+6][n-i+1]=s[n-6*i+5][n-i+1]=‘x‘,
			s[6*i-3][i]=s[6*i-2][i]=s[n-6*i+4][n-i+1]=s[n-6*i+3][n-i+1]=‘y‘,
			s[6*i-1][i]=s[6*i][i]=s[n-6*i+2][n-i+1]=s[n-6*i+1][n-i+1]=‘z‘;
		s[n-1][i]=s[n][i]=s[2][n-i+1]=s[1][n-i+1]=‘p‘;
		for(i=1;i<=n/3;++i)
			s[3*i-2][n/6+2*i-1]=s[3*i-2][n/6+2*i]=‘a‘,
			s[3*i-1][n/6+2*i-1]=s[3*i-1][n/6+2*i]=‘b‘,
			s[3*i][n/6+2*i]=s[3*i][n/6+2*i+1]=‘c‘;
		s[n-1][n/6+2*i-1]=s[n-1][n/6+2*i]=‘a‘,
		s[n][n/6+2*i-1]=s[n][n/6+2*i]=‘b‘;
	}
	if(n%6==4)
	{
		for(i=1;i<=n/6;++i)
			s[6*i-5][i]=s[6*i-4][i]=s[n-6*i+6][n-i+1]=s[n-6*i+5][n-i+1]=‘x‘,
			s[6*i-3][i]=s[6*i-2][i]=s[n-6*i+4][n-i+1]=s[n-6*i+3][n-i+1]=‘y‘,
			s[6*i-1][i]=s[6*i][i]=s[n-6*i+2][n-i+1]=s[n-6*i+1][n-i+1]=‘z‘;
		s[n-3][i]=s[n-2][i]=s[4][n-i+1]=s[3][n-i+1]=‘p‘,
		s[n-1][i]=s[n][i]=s[2][n-i+1]=s[1][n-i+1]=‘q‘;
		for(i=1;i<=n/3;++i)
			s[3*i-2][n/6+2*i-1]=s[3*i-2][n/6+2*i]=‘a‘,
			s[3*i-1][n/6+2*i]=s[3*i-1][n/6+2*i+1]=‘b‘,
			s[3*i][n/6+2*i]=s[3*i][n/6+2*i+1]=‘c‘;
		s[n][n/6+2*i-1]=s[n][n/6+2*i]=‘a‘;
	}
}
int main()
{
	RI i,j;if(scanf("%d",&n),n==2) return puts("-1"),0;//n=2输出-1
	if(n==3) {for(i=1;i<=3;++i) puts(s3[i]);return 0;}//特判n=3
	if(n==5) {for(i=1;i<=5;++i) puts(s5[i]);return 0;}//特判n=5
	if(n==7) {for(i=1;i<=7;++i) puts(s7[i]);return 0;}//特判n=7
	for(i=1;i<=n;++i) for(j=1;j<=n;++j) s[i][j]=‘.‘;//初始化点阵
	if(n&1) for(Draw(n-5),i=1;i<=5;++i) for(j=1;j<=5;++j) s[n-5+i][n-5+j]=s5[i][j-1];else Draw(n);//奇数转化为偶数,然后开始模拟画画
	for(i=1;i<=n;++i) puts(s[i]+1);return 0;//输出答案
}

以上是关于AtCoderAtCoder Grand Contest 041 解题报告(开坑之时已至,目前只有$A,B,C$)的主要内容,如果未能解决你的问题,请参考以下文章

AtCoderAtCoder Grand Contest 041 解题报告(开坑之时已至,目前只有$A,B,C$)

ATcoderAtCoder Beginner Contest 161 题解

ATcoderAtCoder Beginner Contest 159题解

markdown AtCoder Grand Contest 016

css 挑战Boostrap GRAND OEIL

css 挑战Boostrap GRAND OEIL