首页 > 其他分享 >Educational Codeforces Round 151 [div.2 #A-C] 赛后总结(contest/1845)

Educational Codeforces Round 151 [div.2 #A-C] 赛后总结(contest/1845)

时间:2023-07-01 15:33:38浏览次数:56  
标签:151 count Educational contest int ll cin abs ans

\(\textcolor{lightgreen}{A}-\textcolor{yellow}{B}-\textcolor{yellow}{C}-\textcolor{red}{D}-\textcolor{red}{E}-\color{red}{F}\)


A

给你一个数 n ,在给你一个数列 1~k,其中 x 不能用,然后用其他的数任意累加,如能得到 n ,输出所用数字数量和具体数列。

一眼分类。先分是否有 1,有 1 就皆大欢喜;

没 1,那就是可以用 2~k,此时就只要分两种情况:1. k=2,2. k>2 ;

为什么这样分?因为当 k>2 时,就可以用 2,3 组合成所有的数啦。 done.

#A code
#include <bits/stdc++.h>
using namespace std;
const int N = 110;
int t, n, k, x; 
 
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
 
	cin >> t;
	while (t --)
	{
		cin >> n >> k >> x;
		if (k == 1 && x == 1) { cout << "NO" << endl; continue; }
		
		if (x != 1) //1
		{
			cout << "YES" << endl << n << endl;
			for (int i = 1; i <= n; i ++) cout << 1 << ' ';
			cout << endl;
		}
		else 
		{
			if (k == 2) //2
			{
				if (n % 2 != 0) cout << "NO" <<endl;
				else
				{
					cout << "YES" << endl << n/2 << endl;
					for (int i = 1; i <= n/2; i ++) cout << 2 << ' ';
					cout << endl;
				}
			}
			else //2 or 3
			{
				cout << "YES" << endl;
				if (n % 2 == 0)
				{
					cout << n/2 <<endl;
					for (int i = 1; i <= n/2; i ++) cout << 2 << ' ';
				}
				else
				{
					n -= 3;
					cout << n/2+1 << endl;
					for (int i = 1; i <= n/2; i ++) cout << 2 << ' ';
					cout << 3 << endl;
				}
			}
		}
	}
 
	return 0;
}
B

在 Oxy 的 Ⅰ 象限,给出三个不同的点 A,B,C,规定 A 为起点,其余为两个终点,求分别从起点到终点的两条最短路径的最大重合长度。

一开始受上题影响,且一眼没思路,我就又开始分类讨论,分出了四五种情况,越分越复杂......

然后我Q了一下 syz 大佬,发现自己还是一比赛就降智 qwq

两点最短距离就是 xa-xb,xa-xc(y同理,这个就叫做『曼哈顿距离』),

接下来就是分类讨论

image

然后考虑 A 在 B,C任意位置(xb≠xc,yb≠yc)下不同位置的性质

image

可以发现,+1 是所有答案的共有性质,即肯定重合在 A 点,

那么就是判断 x,y 分别是否异号即可(用相乘判断,注意开 long long一直被劝告,永远在忘记) done.

#B code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int t;
struct node
{
	ll x, y;
}a, b, c;

ll count(ll & beg, ll & end)
{
	return beg - end;
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	cin >> t;
	while (t --)
	{
		cin >> a.x >> a.y >> b.x >> b.y >> c.x >> c.y;
		ll lbx = count(a.x, b.x);
		ll lby = count(a.y, b.y);
		ll lcx = count(a.x, c.x);
		ll lcy = count(a.y, c.y);
		ll ans = 0;
		if ((lbx * lcx) > 0) ans += min(abs(lbx), abs(lcx));
		if ((lby * lcy) > 0) ans += min(abs(lby), abs(lcy));
		cout << ++ ans << endl;
    }
	return 0;
}
C

给一个由 0~9 组成的字串 s、一个数 m、两个长度为 m 的字串 l,r ,求是否存在一个数满足在 [l,r] 范围内且不是 s 的子串(不一定是连续的)

  • 首先想到肯定要枚举 l,r ,按从高到低数位 l -> r (不论是否连续,严格从左至右)
    那对于 l -> r 的每一个数位,又肯定要在 s 上查询,看看能否找到;

没找到,那就说明肯定不是它的子串;

  • 找到了,那就标记该位置,为什么嘞?其一是把 \(l[i] \rightarrow r[i]\) 中的所有被标记的位置找到,取其中的最大值,即最靠近 s 的尾巴,这样下一数位的数出现在 s 上的可能性就最小(别忘了严格从左至右,所以 s 标记处的左边就没有再遍历的意义了,所以我这样结论),这是一种贪心思想;
    其二是也从刚刚的话看得出来,标记最远位置 x 后,下一位数就可以直接从 x+1 位开始查询;

  • 那么答案就从最大值这里切入,若是它的子串,最大值撑死了就是 s 的长度。
    so,若不是子串,我们就可以给它赋一个极大值作为在 s 上找不到的标志(其实大于 s 的长度就可以。 done.

顺便提一嘴关于复杂度,Alex_Wei 大犇昨天在 帖子 里回答我说是 \(O(m*m*ls)\Rightarrow O(3*10^7)\) ,是我糊涂了吗(一定是)?,难道测试用例数量 t 不用算进去......

#C code
#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
int t, m;
string s, l, r;

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	
	cin >> t;
	while (t --)
	{
		cin >> s >> m >> l >> r;
		int ls = s.size(), check = -1;
		for (int i = 0; i < m ; i ++)
		{
			int k = check;
			for (char c = l[i]; c <= r[i]; c ++)
			{
				int tmp = inf;
				for (int j = check+1; j < ls; j ++)
				{
					if(s[j] == c)  
					{
						tmp = j;
						break;
					}
				}
				k = max(k, tmp);
			}
			check = k;
		}
		cout << (check == inf ? "YES" : "NO") << endl;
	}
	
	return 0;
}

剩下 D,E,F ,不用看了,我有自知之明,肯定不会做 qwq

总结

这场比赛赛时实际上只过了 A ,但只花了 20min 左右,还是比较快的;

剩下的时间完全就耗在 B 上,思路蛮简单,但我的代码写得很......可以说凌乱,导致我一直能发现漏洞,一直调试,一直 wa ,不断堆砌代码,最后调不出来......

#B 凌乱的代码
#include<bits/stdc++.h>
using namespace std;
int t;
struct node
{
	int x, y;
}a, b, c;

int count(int & beg, int & end)
{
	return beg - end;
}

bool check()
{
    if ((a.x >= b.x && a.x >= c.x && a.y >= b.y && a.y >= c.y) || (a.x <= b.x && a.x <= c.x && a.y <= b.y && a.y <= c.y)) return true;
    return false;
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	cin >> t;
	while (t --)
	{
		cin >> a.x >> a.y >> b.x >> b.y >> c.x >> c.y;
		int lbx = count(a.x, b.x);
		int lby = count(a.y, b.y);
		int lcx = count(a.x, c.x);
		int lcy = count(a.y, c.y);
		int ans = 0;
		bool ikun = false , IKUN = false;
		if ((lbx ^ lcx) < 0) ans += 1;
		else 
		{
			ans += min(abs(lbx), abs(lcx));
			if (check()) ikun = true;
		}
		if ((lby ^ lcy) < 0) ans += 1;
		else 
		{
			ans += min(abs(lby), abs(lcy));
			if (check()) IKUN = true;
		}
		if (ikun && IKUN) ans ++;
		cout << ans << endl;
	}

	return 0;
}

剩下没多少时间了,就懒得看 C 了。(直接开摆

但赛后看 C 还是蛮简单的。

标签:151,count,Educational,contest,int,ll,cin,abs,ans
From: https://www.cnblogs.com/hi-zwjoey/p/17519336.html

相关文章

  • Atcoder Beginner Contest 251-260 EFG
    #251E-TakahashiandAnimals*1261,*环形dpACLink考虑环形dp,对于使用或者不使用\(1\)号饲料分别dp,然后取最小值即可。......
  • Educational Codeforces Round 151 F. Swimmers in the Pool
    一.前言本来打算打打这个比赛玩玩,结果同学找我打游戏王去了,就没打现场(逃)因为是一道不错的数学题,来写写补题的题解这里点名批评@HOLIC喂给我的假题意,让我查错大半天,最后发现题意错了还重新推了好多东西,拳头都硬了等会儿顺便分享下假题意的一种做法二.正文简单题意:有n个......
  • Educational Codeforces Round 151 (Rated for Div. 2)(C,D)
    EducationalCodeforcesRound151(RatedforDiv.2)(C,D)C(dp,子序列自动机)C题目大意就就是给你一个字符串\(s\),还给出两个边界字符串\(l\)和\(r\),长度为\(m\),问我们是否可以构造满足一下条件的字符串\(1\),第\(i\)个字符必须在\(l_i\)和\(r_i\)的双闭区间里面\(2\),......
  • Educational Codeforces Round 151 (Rated for Div. 2) A~D
     A.ForbiddenInteger模拟:voidsolve(){intn,k,x;cin>>n>>k>>x;if(x!=1){cout<<"YES\n"<<n<<"\n";for(inti=1;i<=n;i++)cout<<"1"<<"\n"......
  • Educational Codeforces Round 151 (Rated for Div
    C.StrongPassword给定一个字符串\(s\),一个密码的长度\(m\),下界字符串\(l\)和上界字符串\(r\),上下界字符串长度均为\(m\),且字符只在0~9范围内,上界字符串的第\(i\)位非严格大于下界字符串的第\(i\)位,密码的第\(i\)位需要位于\([l_i,r_i]\)内。问是否存在一个密码不是\(......
  • AtCoder Beginner Contest(abc) 297
    B-chess960题目大意给定一串字符串,里面一定包含2个'B',2个'R',1个'K',问该字符串是否满足以下两个条件,一是两个'B'所在位置奇偶性不同;二是'K'的位置在两个'R'之间解题思路签到题不多嗦了;神秘代码#include<bits/stdc++.h>#defineintlonglongusi......
  • AtCoder Beginner Contest 296 Ex Unite
    洛谷传送门AtCoder传送门不错的dp。考虑按行从上往下dp,并且把列的连通状态塞进dp状态里面。实际上就是塞一个并查集。判状态合法性就是当一个竖的全黑长条结束后,有没有跟别的列连起来。code//Problem:Ex-Unite//Contest:AtCoder-AtCoderBeginnerContest29......
  • AtCoder Beginner Contest 227 H Eat Them All
    洛谷传送门AtCoder传送门好奇特的题。考虑显式建图,那么这是一个\(9\)个结点,\(12\)条边的图,需要找到一条回路使得第\(i\)个点被经过\(a_i\)次。首先会有一个基本思路:先求出每条边经过的次数,然后每条边复制这么多次即可直接构造欧拉回路。其中每条边经过次数的限制就是,......
  • AtCoder Beginner Contest 306(ABC 306) E~F补题
    E题目大意给定数字$k$,规定数组$A$的函数$f(A)$:$A$数组前$k$大数字的和如$A=[1,3,7,~4]$,$k=2$,则$f(A)=7+4=11$现在给定最大数组长度$n$,有$q$组操作,每次将第$x$个数字修改为$y$,输出每次操作后的$f(A)$其中$0<k\leqn\leq5\times10^5,~q\leq5\times......
  • AtCoder Beginner Contest 228 G Digits on Grid
    洛谷传送门AtCoder传送门?这啥啊,不会。考虑行和列分别作为左部点和右部点建二分图(实际上这个建图只是辅助理解,不需要显式建图),每个左部点和每个右部点,边权为格子中的数。容易想到一个dp,设\(f_{i,j}\)为走了\(i\)步,当前在点\(j\),走过的所有边权组成的不同整数的数量。但......