首页 > 其他分享 >AtCoder Beginner Contest(abc) 307

AtCoder Beginner Contest(abc) 307

时间:2023-06-26 18:24:37浏览次数:46  
标签:AtCoder abc idx int 307 ++ v3 size first




A - Weekly Records

题目大意

小莫每天跑步, 输入n周每天的步数, 输出每周跑的总步数;

解题思路

签到题不多嗦了;

神秘代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n, m, k, idx;
signed main() {
	cin >> n;
	int sum = 0;
	for (int i = 1; i <= 7 * n; i++) {
		int x;
		cin >> x;
		sum += x;
		if (i % 7 == 0) {
			cout << sum << ' ';
			sum = 0;
		}
	}
	return 0;
}




B - racecar

题目大意

给定n个字符串, 问能不能从中找出两个字符串拼成一个回文串

解题思路

数据不大, 暴力即可;

神秘代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int, int> PII;
const int N = 5000;
int n, m, k, idx;
vector<string> v;
bool check(string s1,string s2) {
	string s = s1 + s2;
	for (int i = 0, j = s.size() - 1; i < j; i++, j--) {
		if (s[i] != s[j]) return false;
	}
	return true;
}
signed main() {
	cin >> n;
	for (int i = 1; i <= n; i++) {
		string s;
		cin >> s;
		v.push_back(s);
	}
	for (int i = 0; i < v.size(); i++) {
		for (int j = i + 1; j < v.size(); j++) {
			if (check(v[i], v[j])||check(v[j],v[i])) {
				cout << "Yes" << endl;
				return 0;
			}
		}
	}
	cout << "No" << endl;
	return 0;
}




C - Ideal Sheet

题目大意

给定两个图A B, 它们都是由黑色快和透明色块组成的; 现在给出无限大的平面和一个图C, 要求用A和B在平面上拼成C, A和B都只能用一次且可以重叠, 不能剪裁不能旋转, 但是在平面的位置可以随意选择; 注意A和B必须全部用上, 不能只用A不用B;

解题思路

这个题我是真不想写...光是读题就读了好久, 思路不难但是很复杂...;
因为A和B不能旋转和剪裁, 所以我们只要知道一个黑色快的位置, 就能知道其他所有黑色快的位置; 所以我们先取出A和B中的一个点作为参照点; 这个题数据很小, 直接考虑暴力; 我们可以找到C中一个黑色块的位置作为C的参照点, 把A的参照点放在C的参照点上, 然后再遍历C中除了参照点以外的黑色快的位置, 然后算出这个点和C的参照点之间的相对位置, 然后用A的参照点加上这个相对位置, 看看A中有没有黑色快在这个位置上 ( 可以用map存A中黑色块位置 ) , 如果有则标记一下C中这个点的位置 ( 注意是要标记C中的位置, 不要记成A中的 ) , 没有则只能留给B了; 每找完一个C个参照点我们都要算一下 C中有多少个标记的点, 如果数量小于A中黑色块的数量, 那肯定是不符合要求; 如果符合要求就继续再看B, 过程是一样的, 区别只是每次找完C的参照点之后就要看看当前的标记能不能满足题目要求;
因为A和B可以在平面上随意移动, 所以黑色块在A和B上的坐标是没有意义的, 只能用相对位置的坐标;

神秘代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int, int> PII;
const int N =15;
int n, m, k, idx;
map<PII, int> mp1;
map<PII, int> mp2;
map<PII, int> mp3;
vector<PII> v1;
vector<PII> v2;
vector<PII> v3;
bool st1[N][N];
bool st2[N][N];
signed main() {
	idx = 3;
	while (idx--) {
		cin >> n >> m;
		for (int i = 1; i <= n; i++) {
			string s;
			cin >> s;
			for (int j = 0; j < m; j++) {
				if (s[j] == '#') {
					if (idx == 0) {
						v3.push_back({ i,j+1 });
						mp3[{i, j+1}] = 1;
					}
					else if (idx == 1) {
						v2.push_back({ i,j+1 });
						mp2[{i, j+1}] = 1;
					}
					else if (idx == 2) {
						v1.push_back({ i,j+1 });
						mp1[{i, j+1}] = 1;
					}
				}
			}
		}
	}
	int ax = v1[0].first, ay = v1[0].second;
	int bx = v2[0].first, by = v2[0].second;
	for (int i = 0; i < v3.size(); i++) {
		bool f = true;
		memset(st1, false, sizeof st1);
		int cx = v3[i].first, cy = v3[i].second;
		st1[cx][cy] = true;
		int num1 = 1;
		for (int j = 0; j < v3.size(); j++) {
			if (j == i) continue;
			int dx = v3[j].first - cx, dy = v3[j].second - cy;
			if (mp1[{ax + dx, ay + dy}]) {
				st1[v3[j].first][v3[j].second] = true;
				num1++;
			}
		}
		if (num1 < v1.size()) continue;
		for (int k = 0; k < v3.size(); k++) {
			bool f = true;
			memset(st2, false, sizeof st2);
			int cx2 = v3[k].first, cy2 = v3[k].second;
			st2[cx2][cy2] = true;
			int num2 = 1;
			for (int j = 0; j < v3.size(); j++) {
				if (j == k) continue;
				int dx = v3[j].first - cx2, dy = v3[j].second - cy2;
				if (mp2[{bx + dx, by + dy}]) {
					st2[v3[j].first][v3[j].second] = true;
					num2++;
				}
			}
			if (num2 < v2.size()) continue;
			for (auto t : mp3) {
				int a = t.first.first, b = t.first.second;
				if ((!st1[a][b])&&(!st2[a][b])) {
					f = false;
					break;
				}
			}
			if (f) {
				cout << "Yes" << endl;
				return 0;
			}
		}
	}
	cout << "No" << endl;
	return 0;
}




D - Mismatched Parentheses

题目大意

给定一个字符串, 将字符串中被' ( '和' ) '包裹起来的子串和括号一起删除, 输出剩余字符串;

解题思路

用堆来存' ( '的位置, 每找到一个' ) '就删除最顶层左括号的位置, 将其匹配; 最后再遍历字符串, 跳过被标记的区间即可;

神秘代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N =1e6+10;
int n, m, k, idx;
vector<int> v;
map<int, int> mp;
signed main(){
	string s;
	cin >> n >> s;
	for (int i = 0; i < n; i++) {
		if (s[i] == '(') {
			v.push_back(i);
		}
		else if (s[i] == ')') {
			if (v.size() == 0) continue;
			int x = v.back();
			v.pop_back();
			mp[x] = i;

		}
	}
	for (int i = 0; i < n; i++) {
		if (mp[i]) i = mp[i];
		else cout << s[i];
	}
	return 0;
}




E - Distinct Adjacent

题目大意

n个编号为1~n的人按照数字大小做成一圈, 1与n相邻; 现在有0~m-1总共m个数字, 每个人从中选择一个数字; 问有多少选择方式使得没有相邻的两个人选择的数字相同;

解题思路

这个题比较容易想到是一个dp问题; 而难点在于判断第n个人的状态, 而第n个人的状态计算时要考虑第( n-1 )个人和第1个人; 所以我们状态表示为f[i][1]和f[i][0], 前者表示前i个人中, 第1个人和第i个人数字相同的选择方式, 后者则是不同; 所以我们状态计算时, f[i][1] = f[i-1][0], f[i][0] = f[i - 1][0] * (m - 2) + f[i - 1][1] * (m - 1); 很明显f[i][1]是不合法的, 他只是运算过程中所需要的中间量, 所以结果就是f[n][0];
别忘了初始化, f[1][1] = m, f[1][0] = 0;

神秘代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int, int> PII;
const int N = 1e6 + 10, mod = 998244353;
int n, m, k, idx;
int f[N][2], q[N];
signed main(){
	cin >> n >> m;
	f[1][1] = m;
	for (int i = 2; i <= n; i++) {
		f[i][1] = f[i - 1][0];
		f[i][0] = (f[i - 1][0] * (m - 2) + f[i - 1][1] * (m - 1)) % mod;
	}
	cout << f[n][0];
	return 0;
}

标签:AtCoder,abc,idx,int,307,++,v3,size,first
From: https://www.cnblogs.com/mostimali/p/17501875.html

相关文章

  • AtCoder Beginner Contest 307 G Approximate Equalization
    洛谷传送门AtCoder传送门考虑我们如果确定了最终态\(B=(B_1,B_2,...,B_n)\),如何计算最少操作次数。显然从左往右依次使\(A_i=B_i\)。当操作到第\(i\)个位置时,此时\(A'_i=\sum\limits_{j=1}^iA_j-B_j\),所需操作次数为\(|A'_i|\)。令\(C_i=\sum\limits_{......
  • AtCoder Beginner Contest 245 Ex Product Modulo 2
    洛谷传送门AtCoder传送门很好的题。下文令\(k\)为原题面中的\(n\),\(n\)为原题面中的\(k\),\(m\)为原题面中的\(m\)。从一些简单的情况入手。1.\(m\)为质数\(k=0\)的情况是平凡的,只需要要求\(\existsi\in[1,n],a_i=0\)即可。总方案数减去不合法方案数,......
  • AtCoder Beginner Contest 307 ABCDE
    AtCoderBeginnerContest307A-WeeklyRecordsProblemStatement题意:告诉你有几个礼拜,问你每个礼拜走的路程和。Solution思路:按题意模拟,每7天加起来就行。#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;intmain(){ intn; cin>>n; llsum=......
  • AtCoder Beginner Contest 267 ABCDE
    AtCoderBeginnerContest267A-SaturdayProblemStatement题意:问你给定的天到礼拜六还要几天。思路:直接算。#include<bits/stdc++.h>usingnamespacestd;intmain(){ strings; cin>>s; if(s=="Monday")cout<<6-1<<endl; elseif(s=="Tues......
  • AtCoder Beginner Contest 252 Ex K-th beautiful Necklace
    洛谷传送门AtCoder传送门不知道为什么可以想到设\(n_c\)为颜色\(c\)的出现次数,那么\(\prodn_c\)也即选的方案数\(\approx1.25\times10^{11}\)。发现\(B=\sqrt{\prodn_c}\)不大,考虑meet-in-the-middle,把所有颜色分成两部分,每一部分的\(\prodn_c\)都接近\(......
  • abc061d <单源最短路, spfa, 判断负环>
    D-ScoreAttack//https://atcoder.jp/contests/abc061/tasks/abc061_d//单源最短(长)路,spfa,判断负(正)环//本题是找最长的路径,实际上取个负号即可//注意,找到一个负环不能直接结束,只能进行标记cyc[]#include<iostream>#include<algorithm>#include<vect......
  • abc060d <dp, 背包>
    D-SimpleKnapsack//https://atcoder.jp/contests/abc060/tasks/arc073_b//背包问题//特别在于,背包体积极大;但是每个物品间的体积都限制在w[1]~w[1]+3的小范围内//因而可以将所有物品减去一个共同的w[1]的体积偏移,这样背包体积就可以限制在3*n的范围内了......
  • 蔚来手撕代码题:三个线程循环打印ABC
    问题如下:https://www.nowcoder.com/discuss/493178141461041152思路分析三个线程交替打印ABC的实现方法有很多,我个人比较倾向于使用JUC下的CyclicBarrier(循环栅栏,也叫循环屏障)来实现,因为循环栅栏天生就是用来实现一轮一轮多线程任务的,它的核心实现思路如下图所示:Cycl......
  • AtCoder Beginner Contest 212(E,F)
    AtCoderBeginnerContest212(E,F)E(dp)E题目大意为有\(n\)个点,我们需要找到\(k+1\)个点,用数组\(A\)表示,其中,\(A_i\)和\(A_{i+1}\)也不能一模一样,而且,规定\(A_0\)是\(1\),并且\(A_k\)也是\(1\),而且,还要满足下面的\(m\)种条边是不可以代表为\(A_i\)和\(A_{i+1}\),问我们可以......
  • [ABC259F] Select Edges 题解
    Solution考虑树形\(dp\)。我们可以注意到节点\(i\)的相邻的边中被选中的不超过\(d_i\)条,显然我们可以定义状态\(dp_{u,k}\)表示节点\(u\)连接子节点的边有\(k\)条的最大值。但是此处没有给定\(d_i\)的范围,所以对于一个节点最多可能会有\(n-1\)个点,所以时间复杂......