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;
}
解题思路:
使用优先队列来存储每户的编号,去枚举最大疲劳值,通过递推求解答案

浙公网安备 33010602011771号