首页 > 其他分享 >AtCoder Beginner Contest 347 (A~E)

AtCoder Beginner Contest 347 (A~E)

时间:2024-03-31 15:34:05浏览次数:20  
标签:AtCoder cnt const Beginner int ll long 347 MAXN

# AtCoder Beginner Contest 347 (A~E)

这场 C > E > D 不好评价...(D E 赛后一发过,被 C 卡死了)

A

模拟即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 2e5+5;
ll n, k, a[N];
int main(){
	ios::sync_with_stdio(false);
	cin >> n >> k;
	for(int i = 1; i <= n; i ++){
		cin >> a[i];
		if(a[i] % k == 0) cout << a[i] / k << " ";
	}
	return 0;
} 

B

也是直接暴力模拟即可,用 substr 会方便很多。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 2e5+5;
ll ans;
string s;
int main(){
	ios::sync_with_stdio(false);
	map<string, ll> mp;
	cin >> s;
	ll n = s.size();
	for(int i = 1; i <= n; i ++){
		for(int j = 0; j <= n - i; j ++){
			string p = s.substr(j,  i);
			if(!mp[p]) ans ++;
			mp[p] = 1;
		}
	}
	cout << ans << endl;
	return 0;
} 

C

思维难度较大,赛时一直被卡一个点,很烦。

一开始的想法是找出取模后的最大值和最小值只差然后判断小于 a 即可。

如图:

image-20240331150702914

只要 max - min 小于 a 就可以满足,这样做会 wa 1个点。

比如

2 2 1
1 3

应该输出 Yes,但是以上判断会输出 No。

正解:

对取模后的 D 数组排序,若两两之间能塞下一个 b 说明可以通过平移取模使得所有的点都落在小于 a 的范围内再加上之前的判断就可以了。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MAXN = 2e5 + 5;
ll n, a, b, d[MAXN];
int main(){
	cin >> n >> a >> b;
	for(int i = 0; i < n; i ++){
		cin >> d[i];
		d[i] = (d[i] - 1) % (a + b);
	}
	sort(d, d + n);
	for(int i = 1; i < n; i ++){
		if(d[i] - d[i - 1] >= b){
			cout << "Yes" << endl;
			return 0;
		}
	}
	if(d[n - 1] - d[0] < a) cout << "Yes" << endl;
	else cout << "No" << endl;
	return 0;
} 

D

将 c 二进制分解后让 a 和 b 剩余没确定的数尽量相等,如果剩余数不能相等就 -1

再判断 a 和 b 是否大于 \(2^{60}\) 就可以了。

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
const ll MAXN = 2e5+5;
const ll MX = 1<<60;
ll a, b, c;
ll f[70], f1[70], f2[70];
ll fastPow(ll a, ll b){
	ll res = 1;
	while(b){
		if(b & 1) res *= a;
		a *= a;
		b >>= 1;
	}
	return res;
}
int main(){
	ios::sync_with_stdio(false);
	cin >> a >> b >> c;
	ll cnt = 0, ct = 0, c1 = 0, c2 = 0;
	while(c){
		if(c & 1) f[cnt] = 1;
		cnt ++;
		c /= 2;
	}
	for(int i = 0; i <= 60; i ++){
		if(f[i]){
			if((a - c1) >= (b - c2)){
				f1[i] = 1;
				c1 ++;
			}
			else{
				f2[i] = 1;
				c2 ++;
			}
		}
	}
	if((a - c1) != (b - c2)){
		cout << "-1" << endl;
		return 0;
	}
	else{
		ll tt = (a - c1);
		for(int i = 0; i <= 60; i ++){
			if(tt == 0) break;
			if(f1[i] != 1 && f2[i] != 1){
				f1[i] = 1;
				f2[i] = 1;
				tt --;
			}
		}
		if(tt){
			cout << "-1" << endl;
			return 0;
		}
		ll ans1 = 0, ans2 = 0;
		for(int i = 0; i <= 60; i ++){
			if(f1[i] == 1){
				ans1 += fastPow(2, i);
			}
		}
		for(int i = 0; i <= 60; i ++){
			if(f2[i] == 1){
				ans2 += fastPow(2, i);
			}
		}
		cout << ans1 << " " << ans2 << endl;
	}
	return 0;
} 

E

就用 set 模拟 S 然后用一个前缀和维护 |S|, 再用一个 idx 数组表示 某个数的上一个数出现再什么位置然后模拟即可,思维量不大,可以自己想一下。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MAXN = 2e5 + 5;
ll n, q, a[MAXN], s[MAXN], idx[MAXN], ans[MAXN];
int main(){
	ios::sync_with_stdio(false);
	cin >> n >> q;
	set<ll> st;
	ll cnt = 0;
	for(int i = 1; i <= q; i ++){
		cin >> a[i];
		if(st.count(a[i])){
			st.erase(a[i]);
			cnt --;
			
		}
		else{
			st.insert(a[i]);
			cnt ++;
		}
		s[i] = s[i - 1] + cnt;
		if(idx[a[i]]){
			ans[a[i]] += (s[i - 1] - s[idx[a[i]] - 1]);
			idx[a[i]] = 0;
		}
		else idx[a[i]] = i;
		
	}
	for(int i = 1; i <= n; i ++){
		if(idx[i]){
			ans[i] += (s[q] - s[idx[i] - 1]);
		}
		cout << ans[i] << " ";
	}
	return 0;
} 

F

待补......

G

不打算补了。

标签:AtCoder,cnt,const,Beginner,int,ll,long,347,MAXN
From: https://www.cnblogs.com/XiaoMo247/p/18106790

相关文章

  • [ABC347C] Ideal Holidays题解
    [ABC347C]IdealHolidays题解原题传送门原题传送门(洛谷)​ 题意翻译:​ 在\(AtCoder\)王国中,一个周有\(A+B\)天。其中在一周中,\([1,A]\)天是假日,\([A+1,B]\)天是工作日。​ 高桥有\(N\)个计划,第\(i\)个计划安排在\(i\)天后。他不知道今天是周几,但他想知道是否......
  • AT_abc347_d 的题解
    (一)数学题。根据\(C\)的值,可以得出\(x\)和\(y\)有\(s1+s\)个相同的数位和\(s2\)个不同的数位。\(s1\)是\(C\)的二进制中\(0\)的数量,\(s2\)是\(C\)的二进制中\(1\)的数量。\(x\)和\(y\)可以通过在开头放\(s\)个\(1\)的方式既不改变异或大小,又能凑到......
  • AT_abc347_e的题解
    (一)可能因为我太菜了,感觉D>E。用\(vis_i\)表示\(i\)是否出现,\(sum_i\)表示当前集合大小。用vector维护出现的区间的端点。将\(sum\)数组前缀和即可。(二)AC代码。#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;intn,q,x,siz,sum[200010];......
  • AtCoder Beginner Contest 347
    ATlinkProblemAandB略。ProblemC按照模\(a+b\)分类,记录最大值和最小值,如果差值小于等于假期时间即可,否则还需要判断按照\(d_i=D_i\bmod(a+b)\)排序后相邻的两个是否满足条件。ProblemD分离出\(C\)的二进制位,然后对于每一位\(c_i>0\)尝试在\(A,B\)......
  • ABC 347
    C题意:给定\(n\)个数\(d_1\simd_n\),求是否存在一个数\(s\)使得\(1\le(d_i+s)\bmod(a+b)\lea\)。显然可以每个数先模\(a+b\),然后排序。结论:存在当且仅当存在一个数\(i\)使得\((d_{i+1}-d_i)\bmod(a+b)>b\),\(d_{n+1}=d_1\)。F题意:在\(n\timesn\)的矩阵中找......
  • AT_abc347_e 题解
    很水。一个las数组,记录a[i]这个数上一次被加入是什么时候。注意,为防误判,在a[i]被删除的时候,将las[a[i]]设为\(0\)。你也可以这么理解:las是记录在哪出现的visit数组。每次加入一个数的时候,\(\left|S\right|\)就加\(1\),并且使las[a[i]]等于i。删除时,\(\left|S......
  • AtCoder Beginner Contest 347
    A-Divisible(abc347A)题目大意给定\(n\)个数\(a_i\)以及\(k\),输出是\(k\)的倍数的\(a_i\)整除以\(k\)的值。解题思路按照题意判断取模和求整除即可。神奇的代码#include<bits/stdc++.h>usingnamespacestd;usingLL=longlong;intmain(void){ios::syn......
  • AT_abc347_c 题解
    最开始的思路爆炸了我就不写了。先d[i]%=(a+b)。然后,排序,破环为链,相当于存储了下一周。再然后,从\(1\)到\(n\)进行一个循环,若d[i+n-1]-d[i]+1<=a就输出Yes。它的原理是什么?翻译一下上面那个语句,就是“我前一个任务的日期的下一周距离我这个任务的日期小于等于节假日天......
  • ABC347题解
    省流:输+赢D按位分析。既然两个数异或后的结果是\(C\),那就考虑\(C\)中为\(1\)的数中有几个是在\(X\)当中的。假如\(\text{a-popcnt(X)==b-popcnt(Y)}\),那么在\(C\)中为\(0\)的数中随便选\(\text{a-popcnt(x)}\)个即可。注意longlong。codeE假如......
  • AtCoder Beginner Contest 347
    很快做完了AB。然后C就不会做了。随便想了个看似正确的就交了,结果WA*1。后来有交了4发,一发比一发离谱。发现D不难,是一个状态数\(60\times60\times60\)的DP,但是貌似细节很多。写了大约20分钟后无伤过了,发现压根没有需要处理的细节。这时是57min。读完E......