第三届中国计量大学ACM程序设计竞赛个人赛

链接
A:模拟

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define IO ios::sync_with_stdio(false)
#define pb push_back
#define mk make_pair
const int N = 1e5+10;
const int mod = 1e9+7;

string s;
stack<double> sta;
int main(){
	getline(cin, s);
	string str = "";
	for(int i = 0; i < s.size(); i++){
		if(s[i] == ' ') continue;
		if(s[i] == '-') s[i] = '*';
		else if(s[i] == '/') s[i] = '+';
		else if(s[i] == '+') s[i] = '/';
		else if(s[i] == '*') s[i] = '-';
		str += s[i];
	}
	//cout << str << "\n";
	int p = 0, op = 1, flag = 0;
	for(int i = 0; i <= str.size(); i++){
		if(str[i] <= '9' && str[i] >= '0' && i < str.size()){
			p = p*10 + op * (str[i] - '0');
		}
		else{
			if(flag == 1){
				double q = sta.top();
				sta.pop();
				sta.push(p*q);
				//cout << p << " " << q << "**\n";
			}
			else if(flag == 2){
				if(p == 0){
					printf("Cannot be divided by 0\n");
					return 0;
				}
				double q = sta.top();
				sta.pop();
				sta.push(q/p);
				//cout << q << " " << p << "\n";
			}
			else {
				sta.push(p*1.0);
				//cout << p << "\n";
			}
			if(i == str.size()) break;
			p = 0; op = 1; flag = 0;
			if(str[i] == '-') op = -1;
			else if(str[i] == '*') flag = 1;
			else if(str[i] == '/') flag = 2;
		}
	}
	double ans = 0;
	while(!sta.empty()){
		double q = sta.top();
		sta.pop();
		ans += q;
	}
	printf("%.2lf\n", ans);
	return 0;
}

B:

假设 m i n ( x a + y b , x b + y a ) = x a + y b min(x_a+y_b, x_b+y_a)=x_a+y_b min(xa+yb,xb+ya)=xa+yb, m i n ( x a + y c , x c + y a ) = x a + y c min(x_a+y_c, x_c+y_a)=x_a+y_c min(xa+yc,xc+ya)=xa+yc, 要使 x a + y b > x a + y c x_a+y_b>x_a+y_c xa+yb>xa+yc, 则 y b > y c y_b > y_c yb>yc
综上所述,当 x a + y b > x b + y a , x a + y + c > x b + y a , y b > y c x_a+y_b>x_b+y_a, x_a+y+c > x_b+y_a,y_b>y_c xa+yb>xb+ya,xa+y+c>xb+yayb>yc时,选a,b更优,所以按照x_a-y_a从大到小排序,对每个x选前面最大的y形成最优解,取max

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define IO ios::sync_with_stdio(false)
#define pb push_back
#define mk make_pair
const int N = 2e5+10;
const int mod = 1e9+7;

int n;
struct node{
	int a, b, pos;
	bool operator < (const node& e) const {
		return a-b > e.a - e.b;
	}
}e[N];


int main(){
	IO;
	cin >> n;
	for(int i = 0; i < n; i++){
		cin >> e[i].a;
		e[i].pos = i;
	}
	for(int i = 0; i < n; i++){
		cin >> e[i].b;
	}
	sort(e, e+n);
	node no = e[0];
	int ans = 0;
	for(int i = 1; i < n; i++){
		ans = max(ans, e[i].a + no.b);
		if(e[i].b > no.b){
			no = e[i];
		}
	}
	cout << ans <<"\n";
	return 0;
}

D:水题

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define IO ios::sync_with_stdio(false)
#define pb push_back
#define mk make_pair
const int N = 1e5+10;
const int mod = 1e9+7;

int t, x, h, m;

int main(){
	cin >> t;
	while(t--){
		scanf("%d", &x);
		scanf("%d:%d", &h, &m);
		int tm = h*60 + m;
		int y;
		for(int i = 0; i <= 1e6; i++){
			if(tm%10 == 7 || tm%60/10 == 7 || tm/60%10 == 7){
				y = i;
				break;
			}
			tm -= x;
			if(tm < 0){
				tm += 24*60;
			}
		}
		tm %= (24*60);
		h = tm/60, m = tm%60;
		printf("%d %02d:%02d\n", y, h, m);
	}
	return 0;
}

L:

思路来自
其实感觉这题比较简单,但是过题人数好像不太多,我们先思考一下不带修改的括号匹配的过程,很明显我们可以定义一个cnt遇到 ( 就加一,遇到 ) 就减一,然后只要整个过程中cnt都大于等于零,并且最后cnt等于0就说明括号匹配是成功的。那么我们想按照题目修改后会怎么样,其实很容易发现,如果将当前位置的 ( 变为 ) 实际上就是将之后的cnt全部减二,同理如果 ) 变为 ( 其实就是将之后的cnt全部加二。那么我们很容易发现上面的过程和判断包含了区间修改,区间查询和单点查询,所以我们只要用线段树维护修改的过程,每次查询整体的最小是不是大于等于0,并且最后等于0就行了。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define IO ios::sync_with_stdio(false)
#define pb push_back
#define mk make_pair
const int N = 1e5+10;
const int mod = 1e9+7;

int n, m;
char s[N];
int cnt[N], Min[N*4], lazy[N*4];

void build(int o, int l, int r){
	if(l == r){
		Min[o] = cnt[l];
		return ;
	}
	int mid = l+r>>1;
	build(o<<1, l, mid);
	build(o<<1|1, mid+1, r);
	Min[o] = min(Min[o<<1], Min[o<<1|1]);
}

void push(int o){
	if(lazy[o]){
		lazy[o<<1] += lazy[o];
		lazy[o<<1|1] += lazy[o];
		Min[o<<1] += lazy[o];
		Min[o<<1|1] += lazy[o];
		lazy[o] = 0;
	}
}

void up(int o, int l, int r, int ql, int qr, int v){
	if(l >= ql && r <= qr){
		Min[o] += v;
		lazy[o] += v;
		return ;
	}
	push(o);
	int mid = l+r>>1;
	if(mid >= ql) up(o<<1, l, mid, ql, qr, v);
	if(mid < qr) up(o<<1|1, mid+1, r, ql, qr, v);
	Min[o] = min(Min[o<<1], Min[o<<1|1]);
}

int qu(int o, int l, int r, int ql, int qr){
	if(l >= ql && r <= qr){
		return Min[o];
	}
	push(o);
	int res = 1e9, mid = l+r>>1;
	if(mid >= ql) res = min(res, qu(o<<1, l, mid, ql, qr));
	if(mid < qr) res = min(res, qu(o<<1|1, mid+1, r, ql, qr));
	Min[o] = min(Min[o<<1], Min[o<<1|1]);
	return res;
}

int main(){
	IO;
	cin >> n >> m;
	cin >> s+1;
	cnt[0] = 0;
	for(int i = 1; i <= n; i++){
		if(s[i] == '('){
			cnt[i] = cnt[i-1] + 1;
		}
		else cnt[i] = cnt[i-1] - 1;
	}
	build(1, 1, n);
	int x;
	while(m--){
		cin >> x;
		if(s[x] == '('){
			s[x] = ')';
			up(1, 1, n, x, n, -2);
		}
		else{
			s[x] = '(';
			up(1, 1, n, x, n, 2);
		}
		int ans1 = qu(1, 1, n, 1, n);
		int ans2 = qu(1, 1, n, n, n);
		if(ans1 >= 0 && ans2 == 0){
			cout << "Yes\n";
		}
		else cout << "No\n";
	}
	return 0;
}

N:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define IO ios::sync_with_stdio(false)
#define pb push_back
#define mk make_pair
const int N = 1e6+10;
const int mod = 1e9+7;
int t, n;
ll f[N];

int main(){
	IO;
	f[1] = 2;
	for(int i = 2; i <= 1e6; i++){
		f[i] = (f[i-1]*3%mod + 2)%mod;
	}
	cin >> t;
	while(t--){
		cin >> n;
		cout << f[n] << "\n";
	}
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ACM程序设计竞赛基础教程(第2版)》是一本经典的程序设计竞赛教材,旨在帮助学习者掌握ACM程序设计竞赛的基础知识和解题技巧。 该教材以清晰简明的语言详细介绍了ACM竞赛所需的基本知识,包括数据结构、算法设计与分析、动态规划、图论等。同时,它提供了大量的例题和习题,帮助学习者巩固知识,培养解题能力。 与其他类似的教材相比,这本教材具有以下几个特点: 首先,该教材内容全面,不仅介绍了ACM竞赛中常见的基础知识,还涵盖了一些高级内容。通过学习这本教材,学习者能够建立起扎实的程序设计基础,为进一步深入学习和应用打下坚实的基础。 其次,该教材注重实战,提供了大量的例题和习题。这些题目都是经过精心挑选和设计的,能够帮助学习者理解和掌握各种解题技巧。通过反复练习,学习者能够逐渐提高自己的编程水平和解题能力。 最后,该教材配有详细的讲解和解答,帮助学习者更好地理解和掌握知识点。无论是初学者还是有一定基础的学习者,都可以根据自己的情况选择性地学习和提升。 《ACM程序设计竞赛基础教程(第2版)》是一本值得推荐的优秀教材,它不仅适用于参加ACM竞赛的学生,也适用于对算法和程序设计感兴趣的人。通过学习这本教材,学习者能够提高自己的编程能力,锻炼解决问题的思维方式,为将来的学习和工作打下良好的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值