新生训练赛第八场个人题解

比赛链接http://citel.bjtu.edu.cn/vjudge/contest/view.action?cid=328#overview

A:

  • 题意:找出text中含大写字母最多的单词所含大写字母的个数(1~200)
  • 解法:1.有给定text所含字符数的个数,所以可以一个字符一个字符去读 ,每个单词用空格隔开(这种方法比较傻),需要注意的一点是cin不会读入空格,而scanf在读入字符个数n后直接还会读入一个/n,所以需要读入n+1。
  1. #include<bits/stdc++.h>
    using namespace std;
    int main(){
    	char a[222];
    	int n,ma=0,te=0;//ma用来维护最大值,te用来记录当前单词所含最大字符数
    	cin>>n;
    	for(int i=0;i<=n;++i)	scanf("%c",&a[i]);//第一个读入的字符应该是n后面的换行符
    	for(int i=1;i<=n;++i){
    		te=0;
    		while(a[i]!=' '&&i<=n){
    			if(a[i]>='A'&&a[i]<='Z')	++te;
    			++i;
    		} 
    		ma=max(ma,te);
    	}
    	cout<<ma;
    }

         2.用scanf或者cin读入单词,每个单词自动用空格隔开(看完这个就知道读入字符的方式有多蠢了)

              键盘输入Ctrl+C输入结束

  1. #include<bits/stdc++.h>
    using namespace std;
    int main(){
    	char a[222];
    	int n;
    	cin>>n;
    	int te=0,ma=0;
    	while(cin>>a){//读入字符串,直到文件末尾-->while(scanf("%s",a)!=-1)
    		te=0;
    		for(int i=0;i<strlen(a);++i)
    			if(a[i]>='A'&&a[i]<='Z')	
    				te++;
    		ma=max(te,ma); 
    	}
    	cout<<ma<<endl;
    }

B:

  • 题意:改变字符串s,使成为t的子串,输出最少修改次数,以及修改的位置(1~1000)
  • 解法:寻找与s公共字符最多的t的子串的起点,中途维护最大公共字符个数。
  1. #include<bits/stdc++.h>
    using namespace std;
    int main(){
    	string s,t;
    	int n,m;
    	cin>>n>>m>>s>>t;
    	int ma=0,te=0,po=0;//ma维护t子串和s的最大相同字符数,po记录t子串的起点
    	for(int i=0;i<=m-n;++i){
    		te=0;
    		for(int j=0;j<n;++j)	te+=s[j]==t[i+j];
    		if(te>ma){
    			ma=te;
    			po=i;
    		}
    	}
    	cout<<n-ma<<endl;
    	for(int i=0;i<n;++i){
    		if(s[i]!=t[po+i])	cout<<i+1<<" ";
    	}
    } 

C:

  • 题意:对[i-a[i],i-1]区间染色,输出未被染色元素的个数
  • 解法:
  1. 可以用前缀和来做(差分这种说法可能更好理解),改变b[i,j]的值,可以直接改变a[i],a[j+1]的值,对a求前缀和可得数组b.

a 为 b 的差分,即a[i]=b[i]-b[i-1].

  1. #include<bits/stdc++.h>
    using namespace std;
    int a[1111111]={0};
    int main(){
    	long long  n;
    	cin>>n;
    	for(int i=0;i<n;++i){
    		long long k;
    		cin>>k;
    		if(i>k)	k=i-k;
    		else k=0;
    		a[i]++;
    		a[k]--;
    	}
    	int te=0,count=0;
    	for(int i=0;i<n;++i){
    		te+=a[i];
    		count+=!te;
    	}
    	cout<<count<<endl;
    }

2.这是队友的解法。具体解释直接引用。(虽然不知道为什么会超时,一样的代码队友帮我交一遍秒过,我自己交卡一个样例超时,咱啥也不敢说,咱也不敢问。但代码应该是没问题的,这种解法呢,首先对比前一个代码块,明显这个短)

有一排人,每人手里拿着一把长度为 i 米的爪子 ( 为什么是爪子 )同时去捅前面排的人,有几米就能捅几个人,求最后还剩几个人。(好黑暗的题)
思路:
我想从后往前计算会比较方便,从后往前一个个计算出结果,复杂度不会太高,首先比较目前这个人的爪子和他后面那个人的爪子长度 L - 1 的大小,如果大的话不变,如果小的话,说明他后面那个人相较于他捅得更远,我就直接把他后面那个人的爪子长度减一看着他自己的爪子长度,然后看此时他爪子长度是否为0,是的话,说明前面的人活下来了,存活人数加一。最后输出。

  1. #include<bits/stdc++.h>
    using namespace std;
    int main(){
    	int n;
    	cin>>n;
    	int k[n];
    	for(int  i=0;i<n;++i)	cin>>k[i];	
    	int  count=1;
    	for(int  i=n-1;i>0;--i){
    		if(k[i]==0)	count++;
    		if(k[i-1]<=k[i]-1)	k[i-1]=k[i]-1;
    	}
    	cout<<count<<endl;
    }

E:

题意:输出与s相距k的字符串。eg:dist(ac,bd)=dist(a,b)+dis(c,d)=2+2=4

解法:优先选择最大值情况修改消耗k,当不需要最大值修改时修改当前值,k为0结束修改。

若结束修改后k!=0,输出-1;否则输出a

  1. #include<bits/stdc++.h>
    using namespace std;
    long long n,k;
    int main(){
    	char  a[111111]="\0",t[111111]="\0";
    	cin>>n>>k>>a;
    	long long ma=0;
    	int i;
    	for(i=0;i<n;++i){
    		if(a[i]<'n'){
    			if('z'-a[i]<=k){		
    				k-=('z'-a[i]);
    				a[i]='z';
    			}
    			else {
    				a[i]+=k;
    				k=0;
    				break;
    			}
    		}
    		else{
    			if(a[i]-'a'<=k)	{	
    				k-=(a[i]-'a');
    				a[i]='a';
    			}
    			else {
    				a[i]-=k;
    				k=0;
    			break;
    			}
    		}
    	}
    	if(k!=0)	cout<<"-1"<<endl;
    	else cout<<a<<endl;
    }

DF随后补

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值