[解题报告] NOIP 2014 提高组Day2试题
来源:互联网 发布:金和软件官网 编辑:程序博客网 时间:2024/06/05 17:24
[解题报告] NOIP 2014 提高组Day2试题
1.无线网络发射器选址(equation.cpp/c/pas)
【问题描述】
随着智能手机的日益普及,人们对无线网的需求日益增大。某城市决定对城市内的公共场所覆盖无线网
假设该城市的布局为由严格平行的
东西向街道和南北向街道相交形成路口,规定编号为x 的南北向街道和编号为y 的东西向街道形成的路口的坐标是
由于政府财政问题,只能安装一个大型无线网络发射器。该无线网络发射器的传播范围是一个以该点为中心,边长为
例如下图是一个
现在政府有关部门准备安装一个传播参数为d的无线网络发射器,希望你帮助他们在城市内找出合适的安装地点,使得覆盖的公共场所最多
【输入】
输入文件名为wireless.in
第一行包含一个整数
第二行包含一个整数
接下来
【输出】
输出文件名为wireless.out
输出一行,包含两个整数,用一个空格隔开,分别表示能覆盖最多公共场所的安装地点方案数,以及能覆盖的最多公共场所的数量
【数据说明】
对于100%的数据,
题目分析:
水体,模拟即可
注意:边界还是要判的
爱怎么写怎么写
Code
#include <bits/stdc++.h>using namespace std;int MAP[129][129],sum=0,maxn=0;int d,n,k;int work(int x,int y) { int ans=0; for(int i=max(0,x-d);i<=min(128,x+d);i++) { for(int j=max(0,y-d);j<=min(128,y+d);j++) { ans+=MAP[i][j]; } } return ans;}int main() { int x,y; scanf("%d%d",&d,&n); for(int i=1;i<=n;i++) { scanf("%d%d%d",&x,&y,&k); MAP[x][y]=k; } for(int i=0;i<=128;i++) { for(int j=0;j<=128;j++) { int ans=work(i,j); if(ans==maxn) { sum++; }else { if(ans>maxn) { maxn=ans; sum=1; } } } } printf("%d %d",sum,maxn);}
2.寻找道路(road.cpp/c/pas)
【问题描述】
在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件:
1.路径上的所有点的出边所指向的点都直接或间接与终点连通
2 .在满足条件1 的情况下使路径最短
注意:图G中可能存在重边和自环,题目保证终点没有出边
请你输出符合条件的路径的长度
【输入】
输入文件名为road.in
第一行有两个用一个空格隔开的整数
接下来的
最后一行有两个用一个空格隔开的整数
【输出】
输出文件名为road.out
输出只有一行,包含一个整数,表示满足题目描述的最短路径的长度。如果这样的路径不存在,输出-1
【数据说明】
对于30%的数据,
对于60%的数据,
对于100%的数据,
题目分析:
题目一共给出了两个条件,先让我们看看畸形的第一条:
1.路径上的所有点的出边所指向的点都直接或间接与终点连通
这什么鬼?路径上的所有点的出边所指向的点都直接或间接与终点连通
也就是说,能够用的点(也就是最后在答案路径中的点)不仅仅要满足自己能到达终点,与自己直接相连的点也要能够到达终点
那么我们怎么得到能够到达终点的点呢?简单,把边反向,从终点BFS能到达的就是能到达终点的点 ((φ(◎ロ◎;)φ)~晕)
然后我们将不能到达的点反向边连接到的点都标记为不可用,因为它们不满足条件1
那么我们就处理的到了所有能有的点!(条件1完成)
那么条件2我们直接在这些能用的点中跑一边最短路就好了
Code:
#include <bits/stdc++.h> using namespace std;bool go1[10010],go2[10010],dl[10010];int head[3][10010],num[10010];int tot=0;queue <int> q;struct Edge { int to; int next;}edge[400010];int read() { int ans=0,flag=1; char ch=getchar(); while( (ch<'0' || ch>'9') && ch!='-' ) ch=getchar(); if(ch=='-') flag=-1,ch=getchar(); while(ch>='0' && ch<='9') ans=ans*10+ch-'0',ch=getchar(); return ans*flag;}void addedge(int x,int y,int pd) { edge[++tot].to=y; edge[tot].next=head[pd][x]; head[pd][x]=tot; return ;}int main() { memset(num,127,sizeof(num)); int n=read(),m=read(); for(int i=1;i<=m;i++) { int x=read(),y=read(); addedge(x,y,1); addedge(y,x,2); } int s=read(),t=read(); go1[t]=true; q.push(t); while(!q.empty()) { int now=q.front(); q.pop(); for(int i=head[2][now];i;i=edge[i].next) { int to=edge[i].to; if(!go1[to]) { q.push(to); go1[to]=true; } } } for(int i=1;i<=n;i++) { if(!go1[i]) { for(int j=head[2][i];j;j=edge[j].next) { go2[edge[j].to]=true; } } } while(!q.empty()) q.pop(); q.push(s);num[s]=0;dl[s]=true; while(!q.empty()) { int now=q.front(); q.pop(); for(int i=head[1][now];i;i=edge[i].next) { int to=edge[i].to; if(!go2[to] && num[now]+1<=num[to]) { num[to]=num[now]+1; if(!dl[to]) { q.push(to); dl[to]=true; } } } dl[now]=false; } if(num[t]==2139062143) { printf("-1"); return 0; } printf("%d",num[t]); return 0;}
3.解方程(equation.cpp/c/pas)
【问题描述】
已知多项式方程:
求这个方程在
【输入】
输入文件名为equation.in
输入共
第一行包含2个整数
接下来的
【输出】
输出文件名为equation.out
第一行输出方程在
接下来每行一个整数,按照从小到大的顺序依次输出方程在
【数据说明】
对于30%的数据,
对于50%的数据,
对于70%的数据,
对于100%的数据,
题目分析:
这一题怎么看起来像一个数学题呢?
没错,它就是一个数学题
30分做法:
强行求解?你很强,看看
50分做法:
高精吧,貌似是可以的
70分做法(伪100分做法):
既然
但是这样的做法有一些问题:结果有可能错误!并且时间复杂度为
100分做法:
既然一个素数容易错,我们就开一堆!(也就5~6个吧)
发现事实上在
Code:
#include <bits/stdc++.h>using namespace std;int mod[5] ={7457,7829,8623,8971,9781},num[110][5],total,res[50000];bool ans[50000][5],pd[110];int number[10010];bool read() { total=0; memset(number,0,sizeof(number)); bool flag=1; char ch=getchar(); while(ch>'9' || ch<'0' && ch!='-') ch=getchar(); if(ch=='-') flag=0,ch=getchar(); while(ch>='0' && ch<='9') number[++total]=ch-'0',ch=getchar(); return flag;}int ksm(int a,int b,int c) {//快速幂 int r=1; while (b) { if (b&1) r=r*a%mod[c]; b>>=1; a=a*a%mod[c]; } return r;}int main() { int n,m; long long sum; scanf("%d%d",&n,&m); for(int i=0;i<=n;i++) {//这是一个不忍直视的极其复杂的处理方式 if(!read()) pd[i]=1; for(int k=0;k<=4;k++) for(int j=1;j<=total;j++) num[i][k]=((num[i][k]*10%mod[k])+number[j])%mod[k]; } for(int k=0;k<=4;k++) { for(int i=0;i<=min(mod[k],m);i++) { sum=0; for(int j=0;j<=n;j++) { if(pd[j]) sum=(long long)(sum-num[j][k]*ksm(i,j,k))%mod[k]; else sum=(long long)(sum+num[j][k]*ksm(i,j,k))%mod[k]; } if(sum<0) sum+=mod[k]; if(sum==0) { ans[i][k]=1; } } } for(int i=1;i<=m;i++) { res[++res[0]]=i; for(int k=0;k<=4;k++) { if(!ans[i%mod[k]][k]) { res[res[0]--]=0; break; //如果5个素数解都满足,我们就认定这是方程的一个解 } } } for(int i=0;i<=res[0];i++) { printf("%d\n",res[i]); } return 0;}
- [解题报告] NOIP 2014 提高组Day2试题
- NOIP 2015 提高组 day2 解题报告
- [解题报告] NOIP 2014 提高组Day1试题
- Noip 2014 提高组复赛 解题报告
- NOIP 2016 Day2 解题报告
- NOIP 2015 Day2 解题报告
- noip 2015 day2解题报告
- 【noip2014提高组】【Day2】【解题报告】
- 【noip2013】【提高组】【Day2】【解题报告】
- NOIP2013提高组Day2 华容道 解题报告
- 2014 NOIP复赛提高组 C++ 解题报告
- [2011noip day2]7.27test解题报告
- [REVIEW] NOIP 2015 Day2 解题报告
- NOIP 2015 Day2 解题报告(全面)
- NOIP2015提高组Day2 第二题 子串 解题报告
- 2016 NOIP提高组复赛解题报告 C++
- 2015 NOIP提高组 复赛解题报告 C++
- NOIP 2014 提高组 Day2 T2 寻找道路
- perl利用字符串中的数字进行排序
- R中列表元素的访问与修改
- 机器学习故事汇-搞定支持向量机(SVM)
- Java-面向对象构造函数 -(private private)关键字
- 从1.5k到18k, 一个程序员的5年成长之路
- [解题报告] NOIP 2014 提高组Day2试题
- Java的字符类String、StringBuffer与StringBuilder异同对比分析
- loj 6062 (hall定理+ 线段树)
- nginx(2)变量转载自章亦春
- AOP配置
- Hibernate学习(二)
- eclipse新建.dic文件注意——由使用IKAnalyzer分词器新建ext.dic文件引发的思考
- 登录请求超时,后台跳转登录页面时,是在子界面显示登录页面的问题
- rapidjson对Writer的小小封装,方便使用