codeforces 1200 A (模拟)B(模拟) C(几何,思维)

Codeforces竞赛模拟题解析
本文解析了Codeforces平台上的三道模拟题,包括酒店房间分配、木块冒险及圆形走廊移动问题,通过代码示例详细阐述了解题思路。

A. Hotelier(模拟)

题目链接:codeforces 1200A

题意:

    有10个房间 ,给一个字符串中包含 'L', 'R' ,和0 - 9 的数字, L表示从左边往右住, R表示从右边往左边住,数字表示下标为n的离开这个房间

举例 :对于字符串  "LLR1" 表示

第一步 1000000000

第二步 1100000000

第三步 1100000001

第四步 1000000001        最终结果

题解:模拟

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 105;
int a[maxn];
int main(){
	int n;
	cin >> n;
	string s;
	cin >> s;
	int len = s.size();
	string ans = "0000000000";
	for(int i = 0; i < n; i++){
		if(s[i] == 'L'){
			for(int j = 0; j < 10; j++){
				if(ans[j] == '0'){
					ans[j] = '1';
					break;
				}
			}
		}
		else if(s[i] == 'R'){
			for(int j = 9; j >= 0; j--){
				if(ans[j] == '0'){
					ans[j] = '1';
					break;
				}
			}
		}
		else{
			ans[s[i]-'0'] = '0';
		}
	}
	cout << ans << endl;
	return 0;
}

B. Block Adventure(模拟)

题目链接:codeforces 1200B

题意:

    给定n ,m, k  (n表示有n列, m表示袋子中初始值有m个木块, k表示相邻两列的木块个数差值小于等于k则可以移动)

输入n个数, 表示 i 列 有 a[i] 个木块,问是否可以从第一列移动到最后一列

样例解释

3   0   1       (有3列,袋子中初始木块为0, 相邻两列相差小于等于1则可以移动)

4   3   5         输出YES

从第一列出发,可以从第一列中拿出 一个或两个放入袋子中,移动到第二列,从袋子中拿出一个或两个移动到最后一列

 3   1   2    (有3列,袋子中初始木块为1, 相邻两列相差小于等于2则可以移动

1    4    7   输出NO

从第一列出发,可以从袋子中拿出 一个放入第一列中,移动到第二列,无法到达第三列

题解:

        贪心思想,要从当前列拿出尽可能多的木块放入袋子中,从袋子中拿出尽可能少的木块放入当前列

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 105;
int a[maxn];
int main(){
	int t;
	cin >> t;
	while(t--){
		int n, m, k;
		cin >> n >> m >> k;
		for(int i = 1; i <= n; i++){
			cin >> a[i];
		}
		bool flag = true;
		for(int i = 1; i < n; i++){
			if(a[i] >= a[i+1]){          // 当前列的木块大于后一列
				if(k <= a[i+1]){         // 差值小于后一列的值 
					m = m + a[i] - (a[i+1]-k); // 
				}
				else{
					m = m + a[i];          // 拿走当前列的所有木块 放入袋子 
				}
			}
			else{            // 当前列小于后一列 
				if(k > a[i+1]){   // 差值大于后一列的值 
					m = m + a[i]; // 拿走当前列的所有木块放入袋子 
				}
				else{
					if(a[i+1] - a[i] <= k){
						m = m + (k - (a[i+1] - a[i])); // 拿走当前列的(k-(a[i+1]-a[i]))个木块放入袋子
					}
					else{
						if(a[i] + m >= a[i+1] - k){ // 如果可以从袋子中拿出部分满足条件 
							m = m - (a[i+1] - a[i] - k);// 从袋子中拿走部分木块 
						}
						else{       // 否则不行 
							flag = false;
							break;
						}
					}	
				}
			}
		}
		if(flag){
			cout << "YES" << endl;
		}
		else{
			cout << "NO" << endl;
		}
	}
	return 0;
}

C. Round Corridor(几何,思维)

题目链接:codeforces 1200C

题意:

    给出两个数,n,m, q(n代表内层被等分为n份,m代表外层被等分为m份, q代表q次查询),问是否能从当前位置移到指定位置

明显,从(1,1)可以移动到(2,1),(2,2),(1,2),(2,3)其他位置不可以

题解:

    求最小公倍数,表示在某个位置开始封闭,然后判断是否在同一块就可以

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
long long gcd(long long a, long long b){
	return b == 0 ? a : gcd(b, a%b);
}
int main() {
	ll n, m, q, g, ng, mg;
	cin >> n >> m >> q;
	g = gcd(n,m); 
	ng = n / g;        // ng 格为一块
	mg = m / g;        // mg 格为一块
	while(q--) {
		ll sx, sy, ex, ey;
		cin >> sx >> sy >> ex >> ey;
		ll block1, block2;
		sy--;ey--;
		if(sx == 1) {         // 内层
			block1 = sy / ng;
		}
		else {                // 外层
			block1 = sy / mg;
		}
		if(ex == 1) {
			block2 = ey / ng;
		}
		else {
			block2 = ey / mg;
		}
		if(block1 == block2) {
			cout << "YES" << endl;
		}
		else{
			cout << "NO" << endl;
		}
	}
	return 0;
}

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值