NOIP2015普及组试题题解

1.金币

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int ans=0,t=1,n;
int main(){
	cin>>n;
	while(n){
		for(int i=1;i<=t;i++){
			ans+=t;
			n--;
			if(!n)break;
		}
		t++;
	}
	cout<<ans;
	return 0;
}

  

解题思路:

直接模拟,累加金币数即可

 

2.扫雷游戏

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int dx[8]={0,0,1,-1,1,1,-1,-1};
const int dy[8]={1,-1,0,0,1,-1,1,-1};
const int N = 1e2+39+7;
char a[N][N];
int n,m,ans[N][N];
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>a[i][j];
			if(a[i][j]=='*')ans[i][j]=-1;
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(a[i][j]=='*')continue;
			for(int k=0;k<8;k++){
				int x=i+dx[k],y=j+dy[k];
				if(x<1||x>n||y<1||y>m)continue;
				if(a[x][y]=='*')ans[i][j]++;
			}
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(a[i][j]=='*')cout<<'*';
			else cout<<ans[i][j];
		}
		cout<<'\n';
	}
	return 0;
}

  

解题思路:

输入雷区,遍历8个方向,累加判断即可

 

3.求和

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5+39+7,MOD = 1e4+7;
ll n,m,col[N],num[N],ans=0;
ll cnt[N][2],sumx[N][2],sumnum[N][2],summul[N][2];
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++)cin>>num[i];
	for(int i=1;i<=n;i++)cin>>col[i];
	for(int i=1;i<=n;i++){
		ans=(ans+summul[col[i]][i%2]+num[i]*sumx[col[i]][i%2])%MOD;
		ans=(ans+cnt[col[i]][i%2]*i*num[i]+i*sumnum[col[i]][i%2])%MOD;
		cnt[col[i]][i%2]++;
		sumx[col[i]][i%2]+=i;sumx[col[i]][i%2]%=MOD;
		sumnum[col[i]][i%2]+=num[i];sumnum[col[i]][i%2]%=MOD;
		summul[col[i]][i%2]+=i*num[i];summul[col[i]][i%2]%=MOD;
	}
	cout<<ans;
	return 0;
}

  

解题思路:

使用cnt存储同奇偶性的同颜色的格子个数,sumx统计同奇偶性的同颜色的编号和,sumnum统计同奇偶性同颜色的数字和,summul统计同奇偶性同颜色的乘积和,累加起来就是答案

 

4.推销员

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5+39+7;
int n,dis[N],w[N],ans[N],a[N],vh[N],w1[N];
bool cmp(int p,int q){
	int tp=2*dis[p]+w[p];
	int tq=2*dis[q]+w[q];
	return tp>tq;
}
struct cmp2{
	bool operator ()(int p,int q){
		return w[p]<w[q];
	}
};
priority_queue<int,vector<int>,cmp2>q;
int main(){
	cin>>n;
	for(int i=1;i<=n;i++)cin>>dis[i];
	for(int i=1;i<=n;i++)cin>>w[i],w1[i]=i;
	sort(w1+1,w1+n+1,cmp);
	int nowid=0,fp=1;
	for(int i=1;i<=n;i++){
		int maxv=0,id;
		while(fp<=n&&vh[w1[fp]])fp++;
		if(fp<=n){
			maxv=2*(dis[w1[fp]]-dis[nowid])+w[w1[fp]];
			id=w1[fp];
		}
		if(q.size()){
			if(w[q.top()]>maxv){
				maxv=w[q.top()];
				id=q.top();
				q.pop();
			}
		}
		vh[id]=1;
		if(id>nowid){
			for(int j=nowid+1;j<id;j++){
				if(!vh[j]){
					q.push(j);
					vh[j]=1;
				}
			}
			fp++;
			nowid=id;
		}
		ans[i]=ans[i-1]+maxv;
	}
	for(int i=1;i<=n;i++)cout<<ans[i]<<'\n';
	return 0;
}

  

解题思路:

使用优先队列来存储每户的编号,去枚举最大疲劳值,通过递推求解答案

posted @ 2023-05-23 10:13  天雷小兔  阅读(90)  评论(0)    收藏  举报