首页 > 其他分享 >Atcoder ABC 273、 272、271的C、 D

Atcoder ABC 273、 272、271的C、 D

时间:2022-10-31 10:45:36浏览次数:60  
标签:Atcoder ABC end int 272 vec ans it2 dp

ABC 273 C (K+1)-th Largest Number

题意:
给予你一个长度是N的数组a,对于每一个k(0,1,2,... N - 1), 完成一下问题:
找到1 ~ N中的数字a[i],找到大于a[i]的数目恰好是k个不同数的个数

思路:通过二分找到的每一个元素a[i]在数组a中有多少个不同的元素大于a[i]

时间复杂度:O(nlogn)

代码:

#include <bits/stdc++.h>
using namespace std;

const int N = 2e5 + 5;
int a[N];
map<int, int> mp;
int st[N];

int main() {
	int n;
	cin >> n;
	
	vector<int> vt;
	int x;
	for (int i = 1; i <= n; i ++ ) {
		scanf("%d", &a[i]);
		vt.push_back(a[i]);
	}
	
	sort(vt.begin(), vt.end());
	vt.erase(unique(vt.begin(), vt.end()), vt.end());
	
//	for (int i = 0; i < vt.size(); i ++ ) {
//		cout << vt[i] << " ";
//	}
//	cout << endl;
	
	for (int i = 1; i <= n; i ++ ) {
		int ans = 0; 
	
		int l = 0, r = vt.size() - 1;
		while (l < r) {
			int mid = l + r >> 1;
			if(vt[mid] >= a[i]) r = mid;
			else l = mid + 1;
		} 
		
		ans = vt.size() - l - 1;
		st[ans] ++ ;
	}
	
	for (int i = 0; i < n; i ++ ) {
		cout << st[i] << "\n";
	}
	
	
	
	
	return 0;
}

ABC 273 D LRUD Instructions

题意:
在一个矩阵中,你在(r, s)的位置上,根据给定的指令输出你在一个指定指令上可以到达的位置,同时矩阵中存在一些障碍物,遇到障碍物无法再次移动

思路:用map<int, vector > amp, bmp来记录每一个障碍物所在的位置的点,根据所给的方向,通过二分来找到第一个遇到的障碍物(或者是墙体),然后记录输出

时间复杂度:O(qlogn)

代码:

#include <bits/stdc++.h>
using namespace std;


int h, w, n, r, c, q;
map<int, vector<int> > amp, bmp;
//用于横向和纵向的记录每一个障碍物的位置

int main() {
	cin >> h >> w >> r >> c >> n;

	for (int i = 1; i <= n; i ++ ) {
		int rr, cc;
		cin >> rr >> cc;

		amp[rr].push_back(cc), bmp[cc].push_back(rr);
	}
	//值得记忆
	for (auto &p : amp) sort(p.second.begin(), p.second.end());
	for (auto &p : bmp) sort(p.second.begin(), p.second.end());

	cin >> q;
	char d;
	int l;

	for (int i = 1; i <= q; i ++ ) {
		cin >> d >> l;

		if(d == 'L') {
			auto it = amp.find(r);
			int Ib = 0;
			if(it != amp.end()) {
				vector<int> &vec = it -> second;
				auto it2 = lower_bound(vec.begin(), vec.end(), c);
				if(it2 != vec.begin()) it -- , Ib = *it2;

				c = max(c - 1, Ib + 1);
			}
		} else if(d == 'U') {
			auto it = bmp.find(c);
			int Ib = 0;
			if(it != bmp.end()) {
				vector<int> &vec = it -> second;
				auto it2 = lower_bound(vec.begin(), vec.end(), r);
				if(it2 != vec.begin()) it2 -- , Ib = *it2;
			}
		}
		if(d == 'R') {
			auto it = amp.find(r);
			int ub = w+1;
			if(it != amp.end()) {
				vector<int> &vec = it->second;
				auto it2 = upper_bound(vec.begin(), vec.end(), c);
				if(it2 != vec.end()) ub = *it2;
			}
			c = min(c+l, ub-1);
		}
		if(d == 'D') {
			auto it = bmp.find(c);
			int ub = h+1;
			if(it != bmp.end()) {
				vector<int> &vec = it->second;
				auto it2 = upper_bound(vec.begin(), vec.end(), r);
				if(it2 != vec.end()) ub = *it2;
			}
			r = min(r+l, ub-1);
		}
		cout << r << " " << c << "\n";
	}


	return 0;
}

ABC 272 C Max Even

题意:
给予你一个长度为n的数组A,确定是否存在一个偶数是数组A中两个数的总和,如果存在就输出最大的偶数,如果不存在就输出-1

思路:将数组中的奇数和偶数分开,连个奇数可以合成一个偶数,两个偶数可以合成一个偶数,依次知道最大的偶数(此时的0可以归在偶数里)

时间复杂度;O(n)

代码:

#include <bits/stdc++.h>
using namespace std;

const int N = 2e5 + 5;
int a[N];
int n;
int b[N];

bool cmp(int a, int b) {
	return a > b;
}

int main() {
	cin >> n;
	
	int ans = 0, res = 0;
	int sum = 0;
	for (int i = 1; i <= n; i ++ ) {
		int x;
		cin >> x;
				
		if(x % 2 == 0) a[ ++ ans] = x;
		else b[ ++ res] = x;
	}
	
	sort (a + 1, a + 1 + ans, cmp);
	sort (b + 1, b + 1 + res, cmp);

	if(ans <= 1 && res <= 1) cout << -1 << endl;
	else {
		if(ans <= 1 && res > 1) {
			cout << b[1] + b[2] << endl;
		} 
		else if(ans > 1 && res <= 1) {
			cout << a[1] + a[2] << endl;
		}
		else {
			cout << max((a[1] + a[2]), (b[1] + b[2])) << endl;
		} 
	}
	
	
	
	
	return 0;
} 

ABC 272 D Root M Leaper

题意:在一个N * N的矩阵中,你在(1, 1)处,每次可以通过移动到达其他的点,但是每次所达到的点距离上一点
的距离,输出到达每个点最快是第几步,若无法到达则输出-1

思路:首先通过点(0, 0)计算出偏移量,然后直接进行一遍bfs即可

时间复杂度:O(n * n)

代码:

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const int N = 500;

int n, m;
int ans[N][N];

bool vis[N][N];

vector<PII> d;

void bfs(int x, int y) {
	vis[x][y] = 1;
	ans[x][y] = 0;
	
	queue<PII> st;
	st.push({x, y});
	
	while (st.size()) {
		auto p = st.front(); st.pop();
		
		for (int i = 0; i < d.size(); i ++ ) {
			int x = p.first + d[i].first, y = p.second + d[i].second;
			if(x >= 1 && x <= n && y >= 1 && y <= n && !vis[x][y]) {
				ans[x][y] = ans[p.first][p.second] + 1;
				vis[x][y] = 1;
				st.push({x, y});
			}
		}
	}
}

int main() {
	cin >> n >> m;
	
	for (int i = 0; i <= n; i ++ ) {
		for (int j = 0; j <= n; j ++ ) {
			ans[i][j] = -1;
			
			//计算偏移量 
			if(i * i + j * j == m) {
				d.push_back({i, j});
				d.push_back({i, -j});
				d.push_back({-i, j});
				d.push_back({-i, -j});
			}
		}
	}
	
//	for (auto i : d) {
//    	cout << i.first << " " << i.second << endl; 
//	}
	
	bfs(1, 1);
	
	for (int i = 1; i <= n; i ++ ) {
		for (int j = 1; j <= n; j ++ ) {
			cout << ans[i][j] << " ";
		}
		cout << endl;
	}
	
	
	return 0;
} 

ABC 271 C Manga

题意:给予你个有n个数的数组,你可以使用数组中的两个数换成一个你想要的数,问从1开始最长你可以连续到多少

思路:二分查找,再给你个的数组中完成去重之后,通过二分查找可以得出,也可以通过模拟

时间复杂度:O(logn) (可能并不明确)

代码:

#include <bits/stdc++.h>
using namespace std;

const int N = 3e5 + 5;
int a[N];

int n, m;

bool check(int mid) {
	int res = 0;
	
	for (int i = 1; i <= m; i ++ ) {
		res += (a[i] <= mid);
	}
	return (mid - res) * 2 <= (n - res);
}

int main() {
	cin >> n;
	
	for (int i = 1; i <= n; i ++ ) cin >> a[i];
	
	sort(a + 1, a + 1 + n);
	
	m = 1;
	for (int i = 2; i <= n; i ++ ) {
		if(a[i] != a[i - 1]) {
			a[ ++ m] = a[i];
		}
	}	
	
	int l = 0, r = 1e9;
	
	int ans = 0;
	while (l < r) {
		int mid = l + r + 1>> 1;
		if(check(mid)) {
			ans = mid;
			l = mid;
		}
		else r = mid - 1;
	}
	
	cout << l << endl;
	
	
	
	return 0;
} 

ABC 271 D Flip and Adjust

题意:
有n个卡牌,每个卡牌的正反面都有数,你可以让其正面或者反面朝上,问是都有一个顺序可以使得所有朝上的卡牌的总值是S,若没有输出No,若存在输出Yes,并且输出顺序

思路:当时第一眼看到的就是使用dfs,但是n可以取到100,dfs就不行了(这里提醒一下,dfs最大也就是30,爆搜的时间复杂度是指数级别的),所以只能使用dp来解决,
dp (动态规划):
表示:dp[i][j]表示从前n个卡牌中选,总和正好是j的集合
属性:bool
状态转移式:
dp[i][j + a[i]] = dp[i - 1][j] (并且是dp[i - 1][j]状态存在的情况)
dp[i][j + b[i]] = dp[i - 1][j] (dp[i - 1][j]状态存在的情况)

判断dp[n][s]是都存在,若存在通过递归的方式得到摆放顺序
若不存在直接输出No

时间复杂度:O(n * 100000)

代码:

#include <bits/stdc++.h>
using namespace std;

const int N = 1e4 + 10, M = N * 2;
int dp[110][N];
int a[N], b[N];
int n, s;
string ans;

void print(int u, int s) {
	if(u == 0) return ;
	
	if(dp[u - 1][s - a[u]]) {
		print(u - 1, s - a[u]);
		ans += 'H';
	}
	else {
		print(u - 1, s - b[u]);
		ans += 'T';
	}
}

int main() {
	cin >> n >> s;
	
	for (int i = 1; i <= n; i ++ ) cin >> a[i] >> b[i];
	
	//通过动态规划来确定存在状态 
	dp[0][0] = 1;
	for (int i = 1; i <= n; i ++ ) {
		for (int j = 0; j <= 10000; j ++ ) {
			if(dp[i - 1][j]) {
				dp[i][j + a[i]] = dp[i - 1][j];
				dp[i][j + b[i]] = dp[i - 1][j];
			}
		}
	}
	
	cout << dp[n][s] << endl;
	
	if(dp[n][s]) {
		cout << "Yes" << endl;
		print(n, s);
		cout << ans << endl;
	}
	else {
		cout << "No" << endl;
	}
	
	
	return 0;
} 

标签:Atcoder,ABC,end,int,272,vec,ans,it2,dp
From: https://www.cnblogs.com/luoyefenglin/p/16843521.html

相关文章

  • Atcoder试题乱做 Part5
    名言,解决不了题目,那就解决你自己./ybyb\(\text{[ARC136E]Non-coprimeDAG}\)\(\color{blue}{\text{[NORMAL]}}\)考虑\(i\)什么时候能到达\(j\),令\(f_x\)......
  • 【atcoder 293 E - Sugoroku 4】【动态规划,递推】
    importjava.io.IOException;importjava.util.Arrays;importjava.util.Scanner;publicclassMain{staticintn,m,k;staticintMOD=998244353;......
  • P2272 [ZJOI2007]最大半连通子图
    哎,这道题打了半个小时,调了两个小时,最后发现竟然是把\(Tarjan\)里\(while\)给打成\(if\),呜呜,枉费我两个小时时间,所以下次一定要记住不能打成\(if\)(估计也就我一个......
  • AtCoder Beginner Contest 275 E F
    E-Sugoroku4题意:从0走到n,有k次操作,每次会丢出一个骰子,骰子上的数字为\([1,m]\),等概率出现问到达n的概率思路:\(dp[i][k]\)表示用了k次操作到达位置i的概......
  • Atcoder Beginner Contest 275(A~F)
    我好菜啊……又没切掉F,40+min切掉A~E成功滚粗。希望能越打越好吧……赛时A求序列最大值,B简单计算,C数正方形,跳过。D递推不太行,N的范围有点大。但是除法的转移......
  • AtCoder Beginner Contest 275
    咕咕咕咕咕咕。G-InfiniteKnapsack做法1-二分假设第\(i\)个物品选了\(x_i\)个,\(x_i\)为非负整数,有\[\lim_{x\to+\infin}\frac{f(x)}{x}=\frac{\sum_ic_......
  • AtCoder Regular Contest 060
    F题有循环节,一看就有KMP,比较难,太晚了,早上起来再补。C-TakandCards\(n\)个整数\(a_1\sima_n\),问有多少种选数方案,使得选出来的数平均值为\(A\)。\(1\len,a_i......
  • AtCoder Regular Contest 059
    EducationalDPRound(确信C-BeTogether给定\(n\)个数\(a_{1}\sima_n\),你至多可以对每个\(a_i\)操作一次,以\((a_i-y)^2\)的代价令\(a_i\getsy\),求\(a\)全......
  • 【ABC196F】Substring 2(多项式乘法)
    我竟然能在AT当场做出F题!哦,是ABC啊,没事了。以下的字符串均从\(1\)开始记位。以下设\(S_i\)表示字符串\(S\)的第\(i\)位,\(S(l,r)\)表示字符串\(S\)的第......
  • Atcoder Grand Contest 003(A~F)
    赛时打了80分钟,后来因为要处理一些私事就没再打,过掉了ABC,推了DE没推出来,不能算很差,但也不算很好。总结一下吧。赛时A一眼题,统计四个方向是否出现过,如果相对的两......