练习赛3题解

A 随机序列

题解: 极差就是最大值减去最小值,方差就按提上说的模拟
代码:

#include<bits/stdc++.h>

using namespace std;

const int N=1000010;
int a[N];

void Test(){
	int n;
	cin>>n;
	int mx=0,mi=1e8;
	for(int i=1;i<=n;i++)  cin>>a[i];
	double sum=0;
	for(int i=1;i<=n;i++) mx=max(mx,a[i]),mi=min(mi,a[i]),sum+=a[i];
	printf("%d ",mx-mi);
	sum/=n;//平均值 
	double sum1=0;//总和 
	for(int i=1;i<=n;i++){
		sum1+=(sum-a[i])*(sum-a[i]);
	}
	printf("%.3lf\n",sum1/n);
}

int main(){
	ios::sync_with_stdio(false);
	
	int t;
	cin>>t;
	while(t--)
	Test();
} 

B [NOIP2013]记数问题

题解: 从1到n遍历,遍历到 i 时,把 i 每一位分解,记录有多少数位等于x
代码:

#include<bits/stdc++.h>

using namespace std;

const int N=1000010;
int a[N];
int n,x;
void Test(){
	int sum=0;
	cin>>n>>x;
	for(int i=1;i<=n;i++) {
		int j=i;
		while(j){
			sum+=(j%10==x);
			j/=10;
		}
	}
	cout<<sum<<"\n";
}

int main(){
	ios::sync_with_stdio(false);
	
	int t=1;
//	cin>>t;
	while(t--)
	Test();
} 

C 约瑟夫环

题解: 因为最后只留下一个人,可以循环n-1次每次循环当作出队一个人,用a[i]=1表示编号为 i 的人已经出队,a[i]=0表示编号为i的人还未出队,每次循环开始时要先找到第一个没出队的人,在从这个人开始往后找到第m个未出队的人。
代码:

#include<bits/stdc++.h>

using namespace std;

const int N=1000010;
int a[N];
int n,x;
void Test(){
	int n,m,k;
	cin>>n>>k>>m;
	int id=k;
	for(int i=1;i<=n-1;i++){
		while(a[id]==1){//找到第一个未出队的人
			id++;
			if(id==n) id=0; 
		}
		int cnt=0;
		while(1){//找到第m个未出队的人
			if(a[id]==0) cnt++;
			if(cnt==m) break;
			id++;
			if(id==n) id=0;
		}
		a[id]=1;
	}
	for(int i=0;i<n;i++) 
	if(a[i]==0){
		cout<<i;
		return ;
	}
}

int main(){
	ios::sync_with_stdio(false);
	
	int t=1;
//	cin>>t;
	while(t--)
	Test();
} 

D [NOIP2005]校门外的树

题解: 每次都遍历给出起始点和终止点,把起始点和终止点之间的标记,最后遍历0到L,剩余的树的数目就等于未被标记的数目。
代码:

#include<bits/stdc++.h>

using namespace std;

const int N=1000010;
int a[N];
int n,x;
void Test(){
	int n,m;
	cin>>n>>m;
	while(m--){
		int l,r;
		cin>>l>>r;
		for(int i=l;i<=r;i++) a[i]=1; 
	}
    int sum=0;
    for(int i=0;i<=n;i++) sum+=(a[i]^1);
    cout<<sum<<"\n";
}

int main(){
	ios::sync_with_stdio(false);
	
	int t=1;
//	cin>>t;
	while(t--)
	Test();
} 

E 比较月亮大小

题解: 分情况讨论即可
代码:

#include<bits/stdc++.h>

using namespace std;

const int N=1000010;
int a[N];
int n,x;
void Test() {
	int n;
	cin>>n;
	for(int i=1; i<=n; i++) cin>>a[i];

	if(a[n]==0) cout<<"UP";
	else if(a[n]==15) cout<<"DOWN";
	else if(n==1)  cout<<-1;
	else if(a[n]<a[n-1]) cout<<"DOWN";
	else cout<<"UP";
}

int main() {
	ios::sync_with_stdio(false);

	int t=1;
//	cin>>t;
	while(t--)
		Test();
}

F 求距离

题解: 分四种情况:把最小值移到最后,把最小值移到最前面。最大值同理,四种情况取max
代码:

#include<bits/stdc++.h>

using namespace std;

const int N=1000010;
int a[N];
int n,x;
void Test() {
	int n;
	cin>>n;
	for(int i=1; i<=n; i++) cin>>a[i];
	int mx,mi;
	for(int i=1;i<=n;i++){
		if(a[i]==1) mi=i;
		if(a[i]==n) mx=i; 
	}
	int res=0;
	res=max(res,n-mi);
	res=max(res,n-mx);
	res=max(res,mi-1);
	res=max(res,mx-1);
	cout<<res;
}

int main() {
	ios::sync_with_stdio(false);

	int t=1;
//	cin>>t;
	while(t--)
		Test();
}

G 数列下标

题解: 直接两重循环,从i往后遍历,找到第一个大于a[i]的值,可以用一个小优化:如果后面的最大值都小于a[i],那么 a[i] 直接为0.
代码:

#include<bits/stdc++.h>

using namespace std;

const int N=1000010;
int a[N];
int n,x;
void Test() {
	int n;
	cin>>n;
	vector<int>v;
	for(int i=1; i<=n; i++) cin>>a[i];
	int mx=0;
	for(int i=n;i>=1;i--){
		if(a[i]>=mx){
		    mx=a[i];
			v.push_back(0);	
		} 
		else {
			for(int j=i+1;j<=n;j++) {
				if(a[j]>a[i]){
					v.push_back(j);
					break; 
				}
			}
		}
	}
	reverse(v.begin(),v.end());
	for(auto i:v) cout<<i<<" ";
}

int main() {
	ios::sync_with_stdio(false);

	int t=1;
//	cin>>t;
	while(t--)
		Test();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值