NOIP 2013
- Prob.1 转圈游戏
找到循环节,然后快速幂。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int pos[1000005],vis[1000000];
int n,m,k,x,p,mod;
int pow(int a,int b){
int now=1;
while(b){
if(b&1) now=1ll*now*a%mod;
a=1ll*a*a%mod;
b>>=1;
}
return now;
}
int main(){
scanf("%d%d%d%d",&n,&m,&k,&x);
while(!vis[x]){
vis[x]=1; pos[mod++]=x;
x=(x+m)%n;
}
p=pow(10,k);
printf("%d",pos[p]);
return 0;
}
- Prob.2 火柴排队
骚操作啊。我太菜了。
首先,(由于每一列的高度互不相同),我们把每一列分别按高度从小到大的顺序给以每个元素排名,
那么最小的距离和就是 两列中相同的排名两两对应 所计算出来的值。
证明的话,可以考虑交换两个组合的元素,发现计算出的权值只会变大。
为了把相同的名次对应,
所以就是要把两个序列都从小到大排序或者都从大到小排序么?
蠢蠢的我想到了上面这个东西,但显然错了,然后我就不知道如何搞了。
正解:
其实两列的交换是等价且相互的
也就是说,我们可以只通过对第一列进行交换达到相同名次对应的目的。
所以我们映射出第一个序列的每个元素在第二个序列中的出现的位置,得到一个新的序列,
求出这个新的序列的逆序对数就是答案了。
(这个题太强辣。%%%)
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 100005
using namespace std;
const int mod=99999997;
int cc[MAXN],A[MAXN],B[MAXN],p[MAXN];
int n,ans;
void readwork(int *a){
for(int i=1;i<=n;i++) scanf("%d",&a[i]),cc[i]=a[i];
sort(cc+1,cc+n+1);
for(int i=1;i<=n;i++) a[i]=lower_bound(cc+1,cc+n+1,a[i])-cc;
}
void merge(int *a,int l,int r){
static int tmp[MAXN];
if(l==r) return;
int mid=(l+r)>>1;
merge(a,l,mid);
merge(a,mid+1,r);
int h=l,t=mid+1,pp=l;
while(h<=mid&&t<=r){
if(a[h]<a[t]) tmp[pp++]=a[h++];
else ans=(1ll*ans+mid-h+1)%mod,tmp[pp++]=a[t++];
}
while(h<=mid) tmp[pp++]=a[h++];
while(t<=r) tmp[pp++]=a[t++];
for(int i=l;i<=r;i++) a[i]=tmp[i];
}
int main(){
scanf("%d",&n);
readwork(A); readwork(B);
for(int i=1;i<=n;i++) p[B[i]]=i;
for(int i=1;i<=n;i++) A[i]=p[A[i]];
merge(A,1,n);
printf("%d",ans);
return 0;
}
- Prob.3 货车运输
先是最大生成树,保证了路径的最小值最大;
然后在倍增,进行树上RMQ就好了。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
struct Cm_edge{
int u,v,w;
bool operator <(const Cm_edge &rtm){
return w>rtm.w;
}
}E[50005];
struct Lk_edge{
int to,val,next;
}e[20005];
int head[10005],fa[10005],dep[10005],stm[10005][15],stf[10005][15];
int n,m,Q,ent=2;
void add(int u,int v,int w){
e[ent]=(Lk_edge){v,w,head[u]};
head[u]=ent++;
}
void cmin(int &a,int b){
if(a>b) a=b;
}
int find(int u){
return u==fa[u]?u:fa[u]=find(fa[u]);
}
void dfs(int u,int dad,int val){
stf[u][0]=dad; stm[u][0]=val; dep[u]=dep[dad]+1;
for(int k=1;k<=14;k++){
stf[u][k]=stf[stf[u][k-1]][k-1];
if(!stf[u][k]) break;
stm[u][k]=min(stm[u][k-1],stm[stf[u][k-1]][k-1]);
}
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(v==dad) continue;
dfs(v,u,e[i].val);
}
}
int query(int u,int v){
if(find(u)!=find(v)) return -1;
int ans=INF;
if(dep[u]>dep[v]) swap(u,v);
for(int k=14;k>=0;k--){
if(dep[stf[v][k]]<dep[u]) continue;
cmin(ans,stm[v][k]); v=stf[v][k];
}
if(u==v) return ans;
for(int k=14;k>=0;k--){
if(stf[u][k]==stf[v][k]) continue;
cmin(ans,stm[u][k]); cmin(ans,stm[v][k]);
u=stf[u][k]; v=stf[v][k];
}
cmin(ans,stm[u][0]); cmin(ans,stm[v][0]);
return ans;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++) scanf("%d%d%d",&E[i].u,&E[i].v,&E[i].w);
sort(E+1,E+m+1);
for(int i=1;i<=n;i++) fa[i]=i;
for(int i=1,u,v,w,fu,fv;i<=m;i++){
u=E[i].u,v=E[i].v,w=E[i].w;
fu=find(u); fv=find(v);
if(fu==fv) continue;
fa[fv]=fu;
add(u,v,w); add(v,u,w);
}
memset(stm,0x3f,sizeof(stm));
dfs(1,0,INF);
scanf("%d",&Q);
for(int i=1,u,v;i<=Q;i++){
scanf("%d%d",&u,&v);
printf("%d\n",query(u,v));
}
return 0;
}
- Prob.4 积木大赛
思路很巧妙的题。
之前想的是维护出每层的连续的段数和。实现很麻烦,而且复杂度堪忧。
正解:
从左到右枚举,考虑当前的高度 h[i] :
(可以想象成首先我们已经搭好了1~i-1,现在告诉你需要在第i列搭 h[i]的高度)
如果 h[i-1]>=h[i] 那么显然,在我们搭好 i-1那一列是可以顺带把 第i列搭好。
如果 h[i-1]<h[i] 那么高度h[i]的下面部分,即1~h[i-1],也可以在搭 i-1那一列是可以顺带搭好。
剩下的 h[i]-h[i-1] 就要另外搭了,即贡献答案, ans+=h[i]-h[i-1]。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int main(){
int n,a=0,b=0,ans=0;
scanf("%d",&n);
for(int i=1;i<=n;i++){
a=b; scanf("%d",&b);
if(a<b) ans+=b-a;
}
printf("%d",ans);
return 0;
}
- Prob.5 花匠
求最大拐点数,贪心做就好。
考虑连续的三个数 a,b,c令 a<b 并且选了a,b
1).如果b<c,那么不贡献答案,并弃掉b,改为选c,这样可以使得以后下降的范围相比b更大。
2).如果b>c,那么显然该选择c,一是可以贡献一个答案(出现了拐点),二是使得以后上升的范围相比b更大。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<set> using namespace std;
int n,k,now,pre,ans=1;
int main(){
scanf("%d",&n); scanf("%d",&pre);
for(int i=2;i<=n;i++){
scanf("%d",&now);
if(now>pre&&k!=1) k=1,ans++;
if(now<pre&&k!=2) k=2,ans++;
pre=now;
}
printf("%d",ans);
return 0;
}
- Prob.6 什么“华容道”吧,没做了。
NOIP 2013的更多相关文章
- NOIP 2013 货车运输【Kruskal + 树链剖分 + 线段树 】【倍增】
NOIP 2013 货车运输[树链剖分] 树链剖分 题目描述 Description A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在 ...
- Luogu 1979 NOIP 2013 华容道(搜索,最短路径)
Luogu 1979 NOIP 2013 华容道(搜索,最短路径) Description 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面 ...
- [Noip 2013 Day1-3] 货车运输 做法总结
[Noip 2013 Day1-3] 货车运输 做法总结 Online Judge:Luogu-1967 Label:启发式合并,离线,整体二分,按秩合并,倍增,最大生成树 打模拟离线赛时做到,顺便总 ...
- 【CodeVS 3290】【NOIP 2013】华容道
http://codevs.cn/problem/3290/ 据说2013年的noip非常难,但Purpleslz学长还是AK了.能A掉这道题真心orz. 设状态$(i,j,k)$表示目标棋子在$(i ...
- 【NOIP 2013 DAY2 T3】 华容道(spfa)
题目描述 [问题描述] 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面, 华容道是否根本就无法完成,如果能完成, 最少需要多少时间. 小 ...
- 水题挑战1:NOIP 2013 选择客栈
丽江河边有\(n\) 家很有特色的客栈,客栈按照其位置顺序从 \(1\) 到 \(n\) 编号.每家客栈都按照某一种色调进行装饰(总共 \(k\) 种,用整数 \(0 \sim k-1\) 表示),且 ...
- NOIP 2013 货车运输 最大生成树加DFS巧妙AC
#include<set> #include<map> #include<cmath> #include<queue> #include<stac ...
- 【CodeVS 3289】【NOIP 2013】花匠
http://codevs.cn/problem/3289/ dp转移,树状数组维护前缀max和后缀max进行优化,$O(nlogn)$. #include<cstdio> #includ ...
- NOIp 2013 #3 转圈游戏 Label:模拟
题目描述 n 个小伙伴(编号从 0 到 n-1)围坐一圈玩游戏.按照顺时针方向给 n 个位置编号,从0 到 n-1.最初,第 0 号小伙伴在第 0 号位置,第 1 号小伙伴在第 1 号位置,……,依此 ...
- NOIp 2013 #2 花匠 Label:爆0的Water
题目描述 花匠栋栋种了一排花,每株花都有自己的高度.花儿越长越大,也越来越挤.栋栋决定 把这排中的一部分花移走,将剩下的留在原地,使得剩下的花能有空间长大,同时,栋栋希 望剩下的花排列得比较别致. 具 ...
随机推荐
- python3.* socket例子
On Server: # -*- coding: utf-8 -*-#this is the server import socketif "__main__" == __name ...
- Struts2之Action的实现
对于Struts2框架来说,最重要的莫过于Action类的编写,类比于Servlet,Action类也是通过类的实例对象调用方法来处理请求的,Action类的实例对象是由Struts2的核心Filte ...
- EL表达式 与 servlvet3.0的新规范
EL表达式 EL表达式 是一种简化的数据访问方式,是对jsp脚本的简化 . 如我们在一个页面中需要输出session的保存的一个值: <% out.println(session.getAt ...
- IT学习逆袭的新模式,全栈实习生,不8000就业不还实习费
大家好: 我是马伦,也就是多年耕耘在IT培训一线的老马.老马一直怀揣普惠教育梦想初心,一直为莘莘学子能获得高质量的IT教育服务而奋斗. 之前老马在IT培训机构任职讲师多年,也有丰富的教学管理经验.接触 ...
- 学习ASP.NET Core Razor 编程系列四——Asp.Net Core Razor列表模板页面
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
- Mysql必须知道的知识
最近在准备面试,所以也整理了一些Mysql数据库常用的知识,供大家参考. 1.MySQL的复制原理以及流程 (1).复制基本原理流程 1. 主:binlog线程--记录下所有改变了数据库数据的语句,放 ...
- 读论文系列:Object Detection ECCV2016 SSD
转载请注明作者:梦里茶 Single Shot MultiBox Detector Introduction 一句话概括:SSD就是关于类别的多尺度RPN网络 基本思路: 基础网络后接多层featur ...
- python 之 列表list && 元组tuple
目录: 列表 列表基本操作 列表的操作符 列表的函数和方法 元组 介绍: 列表是一种可变的有序集合,可以进行访问.添加和删除操作. 元组是一种不可变的有序集合,可以访问. 1.列表的基本操作 创建列表 ...
- Java Jar包压缩、解压使用指南
什么是jar包 JAR(Java Archive)是Java的归档文件,它是一种与平台无关的文件格式,它允许将许多文件组合成一个压缩文件. 如何打/解包 使用jdk/bin/jar.exe工具,配置完 ...
- maven常见问题处理(3-1)修改maven 默认使用的 jdk 版本
Eclipse工程应设定了1.8,maven编译仍然使用1.6的解决办法 解决方式有两种,一种是配置 pom.xml,一种是配置 settings.xml. 方式一:settings.xml 配置 打 ...