首页 > 其他分享 >NOIP2017普及组试题题解

NOIP2017普及组试题题解

时间:2023-05-22 17:13:32浏览次数:53  
标签:NOIP2017 试题 int 题解 sum precolor long ll dp

1.成绩

原题:https://www.luogu.com.cn/problem/P3954

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int a,b,c;
int main(){
	cin>>a>>b>>c;
	cout<<a/10*2+b/10*3+c/10*5;
	return 0;
}

  

解题思路:

因为数据保证a,b,c都是10的整倍数,所以直接做加法就行了

 

2.图书管理员

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e3+255,w[39]={1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
int n,q,p[N];
int main(){
	cin>>n>>q;
	for(int i=1;i<=n;i++)cin>>p[i];
	sort(p+1,p+n+1);
	for(int i=1,x,b;i<=q;i++){
		bool flag=0;
		cin>>x>>b;
		for(int j=1;j<=n;j++){
			if(p[j]%w[x]==b){
				cout<<p[j]<<'\n';
				flag=1;
				break;
			}
		}
		if(!flag)cout<<-1<<'\n';
	}
	return 0;
}

  

解题思路:

列举出10的次幂,每次去模10的次幂,判断是否相同即可

 

3.棋盘

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e3+255,dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
int a[N][N],m,n,ans=1e9,dp[N][N];
void dfs(int x,int y,int precolor,int sum){
	if(x==m&&y==m){
		if(ans>sum)ans=sum;
		return;
	}
	if(sum>=dp[x][y])return;
	else dp[x][y]=sum;
	for(int i=0;i<4;i++){
		int xx=x+dx[i],yy=y+dy[i];
		if(xx<1||xx>m||yy<1||yy>m)continue;
		if(a[xx][yy]==precolor){
			dfs(xx,yy,precolor,sum);
			continue;
		}else if(!a[xx][yy]&&precolor==a[x][y]){
			dfs(xx,yy,precolor,sum+2);
		}else if(a[xx][yy]){
			dfs(xx,yy,a[xx][yy],sum+1);
		}
	}
}
int main(){
	memset(a,0,sizeof(a));
	memset(dp,1,sizeof(dp));
	cin>>m>>n;
	for(int i=1;i<=n;i++){
		int x,y,z;
		cin>>x>>y>>z;
		a[x][y]=z+1;
	}
	dfs(1,1,a[1][1],0);
	if(ans!=1e9)cout<<ans;
	else cout<<"-1";
	return 0;
}

  

解题思路:

记录每个格子的颜色,进行深搜,分三种情况:第一种,下一个格子的颜色与precolor相等,直接dfs;第二种,下一个格子无色,且当前格子与precolor颜色相等,金币数+2;第三种,下一个格子有色,但和当前格子颜色不同,金币数+1。再加上最优性剪枝,这道题就可以AC了

 

4.跳房子

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 5e5+255;
ll n,d,k,x[N],s[N],sum=0,dp[N],maxdis,jid;
bool dpp(ll fir,ll sec){
	memset(dp,200,sizeof(dp));
	deque<int>q;
	dp[0]=0;int fp=0;
	for(int i=1;i<=n;i++){
		while(fp<i&&x[i]-x[fp]>=fir){
			while(q.size()&&dp[q.back()]<=dp[fp])q.pop_back();
			q.push_back(fp);
			fp++;
		}
		while(q.size()&&x[i]-x[q.front()]>sec)q.pop_front();
		if(q.size())dp[i]=max(dp[i],dp[q.front()]+s[i]);
		if(dp[i]>=k)return 1;
	}
	return 0;
}
int main(){
	cin>>n>>d>>k;
	for(int i=1;i<=n;i++){
		cin>>x[i]>>s[i];
		sum+=(s[i]>0?s[i]:0);
		if(s[i]>0){
			maxdis=max(maxdis,x[i]-x[jid]);
			jid=i;
		}
	}
	if(sum<k){
		cout<<-1;
		return 0;
	}else{
		int l=-1,r=maxdis;
		while(l+1<r){
			int mid=(l+r)/2;
			if(dpp(max(1ll,d-mid),d+mid))r=mid;
			else l=mid;
		}
		cout<<r;
	}
	return 0;
}

  

解题思路:

求出每个距离中最大的差值,进行二分。在判断是否可行时,使用了双端队列来优化,这样可以排除不用的数据,使复杂度大大降低

标签:NOIP2017,试题,int,题解,sum,precolor,long,ll,dp
From: https://www.cnblogs.com/zhanghx-blogs/p/17421104.html

相关文章

  • III.追想 题解
    原题链接我第一次出的一道比较正经的菜题,欢迎大家来切哦。感谢魔法少女老干妈GM_Joanna_的支持对于操作1,3:注意到1e9的数据至多5此操作就能把一个位置变为0,这个次数可视为常数。考虑每个位置暴力改,也只会递归\(5\timesn\logn\)次。对于3操作,考虑最坏的情况,每......
  • 9万多条执业医师资格考试题库ACCESS\EXCEL数据库
    《9万多条执业医师资格考试题库ACCESS数据库》搜集了大量执业医师资格考试试题,包括临床执业医师资格考试试题、口腔执业医师资格考试试题、中医执业医师资格考试试题、中西医结合执业医师资格考试试题、公卫执业医师资格考试试题等。分类情况包含:临床执业医师(22428条)、口腔执业......
  • 1万多条司法资格考试题库ACCESS\EXCEL数据库
    《1万多条司法资格考试题库ACCESS版》搜集了大量司法资格考试试题,包括试卷一、试卷二、试卷三、试卷四等科目。同类的数据库有《9万多条执业医师资格考试题库ACCESS数据库》、《6万多条会计从业资格考试题库ACCESS版》、《近7万多条证券从业资格考试题库ACCESS版》、《1万多条一级......
  • 程序设计进阶模拟试题
    题目描述程序定义了NxN的二维数组,并在主函数中自动赋值。请编写函数fun,函数的功能是:使数组右上三角元素中的值乘以m。#include<stdio.h>#include<conio.h>#include<stdlib.h>#defineN5intfun(inta[][N],intm)/不得改动此注释文字及位置,begein/{}/不得改动此注释文字......
  • 【题解】Atcoder ABC302 F,G,Ex
    完全不会G和Ex,这些套路还是要积累一下的。F.MergeSet题目描述:给定\(n\)个集合,每次可以合并两个有交的集合,问最少多少次合并可以让\(1\)和\(m\)位于同一个集合中。题目分析:一开始将题读成了将\([1,m]\)位于同一个集合中,然后就感觉这个题相当不可做。因为集合的元......
  • NOIP2018普及组试题题解
    1.标题统计原题:https://www.luogu.com.cn/problem/P5015#include<bits/stdc++.h>#definelllonglongusingnamespacestd;strings;intans=0;intmain(){ getline(cin,s);intlen=s.length(); for(inti=0;i<len;i++){ if(s[i]>='0'&&......
  • #球钟算法题解以及代码完成
    球钟问题描述:球钟是一个利用球的移动来记录时间的简单装置。它有三个可以容纳若干个球的指示器:分钟指示器,五分钟指示器,小时指示器。若分钟指示器中有2个球,5分钟指示器中有6个球,小时指示器中有5个球,则时间为5:32。       工作原理:每过一分钟,球钟就会从球队列的队首......
  • 经典面试题
    TC经典面试题1.赛马问题WY经典面试题2.:烧香问题砝码称重问题有36匹马,6个跑道,在没有计时器的情况下,至少需要赛马多少次,才能比出前三名?答案:至少需要比较8次。解题思路:先把36匹马平均分成6组,假设为A,B,C,D,E,F,让每组的马赛跑一次,假设各组的名次分别为A1>A2>A3>A4>A5>A6,其他组也是如此,决......
  • abc302 题解
    打的还行,加的分不多。A直接除完上取整即可。#include<bits/stdc++.h>usingnamespacestd;typedeflonglongLL;constintN=1e5+5,INF=0x3f3f3f3f;constLLmod=1e9+7;intmain(){ios::sync_with_stdio(false);cin.tie(nullptr); LLa,b; ci......
  • react面试题汇总1
    请介绍一下React的生命周期函数及其调用顺序。答:React的生命周期函数分为三个阶段:挂载、更新和卸载。以下是各个生命周期函数的名称及调用顺序:挂载阶段constructor():组件构造函数,在最开始时调用。staticgetDerivedStateFromProps():从props中派生出state,返回新的state值,会在render......