CF教育场58 + 67

58场
A题:
求不在[l,r]内的数并且可以除于d,当d<l || d < r时就直接输出,然后只剩下判断d>r
的部分。r-r%d(r减去r比d多出的部分,则该数可被d除再加上d就为答案)

#include <cstdio>
int main(){
	int n , l , r , d ; 
	scanf ("%d",&n) ;
	while(n--){
		scanf ("%d%d%d",&l,&r,&d);
		if (d < l || d > r)		printf ("%d\n",d) ;
		else
			printf ("%d\n",d+(r-r%d)) ;
	}
	return 0 ; 
}

B题:
题意:给出一串字符串,求形如[:|||:]的长度,这里[] ::要配对然后再加上中间|的数,(一开始理解为括号配对。。。)从前面搜索“[” 和“[”后面第一个“:”,再从后面找出第一个“[” 和“[”前面面第一个“:”,然后计算中间的‘|’数量最后加上4即可(“[]” 和": :")

#include <cstdio> 
#include <iostream>
#include <stack>
#include <cstring> 
using namespace std ; 
int main(){
	int len = 0 ;
	string ch ; 
	cin >> ch ; 
	int a = 0 , b = 0 ; 
	for (int i = 0 ; i < ch.size() ; ++ i){
		if (ch[i] == '['){
			for (int j = i+1 ; j < ch.size() ; ++ j){
				if (ch[j] == ':'){
					a = j ; 
					break ; 
				}
			}
			break ; 
		}
	}
	if (a > 0){
		for (int i = ch.size()-1 ; i > a ; -- i){
			if (ch[i] == ']'){
				for (int j = i-1 ; j > a ; --j){
					if (ch[j] == ':'){
						b = j ; 
						break ; 
					} 
				}
				break ; 
			}
		}
	}
	
	if (a < b){
		for (int i = a+1 ; i < b ; ++ i)
			if (ch[i] == '|')
				++len ; 
		printf ("%d\n",len+4) ;
	}
	else    printf("-1\n") ;  
	return 0 ; 
}

E题:
题意:+ 时加上一张x * y的账单,?询问 x * y的钱包能不能装下所有的账单。
用h存当前账单的最长宽度,w存最长高度。x y输入时x为大的数,否则交换然后判断即可。

#include <cstdio> 
int main(){
	int n ;
	int x , y , h = 0 , w = 0 ;
	char ch ;  
	scanf ("%d",&n) ;
	getchar() ;
	while(n --){
		scanf ("%c %d %d",&ch,&x,&y) ;
		getchar() 
		;if (y > x){
			int t = x ; 
			x = y ; 
			y = t ; 
		}
		if (ch == '?'){
			if (x>=h && y >= w)		printf ("YES\n") ;  
			else	printf ("NO\n") ;
		}
		else{
			h = h>x ? h : x ; 
			w = w>y ? w : y ;
		}
	}	
	return 0 ;
}

67场

  • A题:
#include <cstdio>
#include <algorithm>
#include <iostream>
using namespace std; 
int main(){
	int p ; 
	cin >> p ; 
	while(p--){
		long long n , s , t ;
		cin >> n >> s >> t ; 
		if (n==s && n==t)	cout << "1" << endl ; 
		else if (s==n)	cout << n-t+1 << endl ;
		else if (t==n)	cout << n-s+1 << endl ;	 
		else if (s+t >= n){
			cout << n-min(s,t)+1 << endl ; 
		}
		else{
			cout << n-max(s,t)+1 << endl ;
		}
	}
	return 0 ; 
}

可直接化简为:

#include <cstdio>
#include <algorithm>
using namespace std; 
int main(){
	int p ; 
	scanf ("%d",&p) ;
	while(p--){
		int n , s , t ;
		scanf ("%d%d%d",&n,&s,&t) ;
		if (n==s && n==t)	printf ("1\n") ; 
		else	printf ("%d\n",n-min(s,t)+1) ; 
	}
	return 0 ; 
}
  • B题:

给出字符串s,然后再给出m个字符串,求最短包含t的所有字母的s的长度。
做法:用一个vis不定数组存储s中每个字母出现的下标,用p存放t每个字母出现的次数,然后用p的次数索引vis出当前字母出现的下标,用pos存放最大值。

#include <cstring>
#include <iostream>
#include <vector>
using namespace std ; 
vector<int> vis[26] ; 
int f[30] ; //记录t字符串每个字母出现的次数 
int main(){
	ios::sync_with_stdio(false);
	string s , t ; 
	int n , m ; 
	cin >> n ; 
	cin >> s ; 
	for (int i = 0 ; i < s.size() ; ++ i){
		vis[s[i] - 'a'].push_back(i) ; 	//存放每一个字母出现的下标 
	}
	cin >> m ; 
	while(m --){
		cin >> t ;
		int pos = 0 ;  
		memset(f,0,sizeof(f)) ;  
		if (t.size() == s.size()){
			cout << t.size() << endl ; 
			continue ; 
		}
		for (int i = 0 ; i < t.size(); ++ i){
			int cur = t[i] - 'a' ;
			pos = max(pos,vis[cur][f[cur]++]) ; 
		}
		cout << pos+1 << endl ; 
	}
	return 0 ; 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值