noip2009提高组题解
NOIP2009题解
T1:潜伏者
题目大意:给出一段密文和破译后的明文,一个字母对应一个密文字母,要求破译一段密文,如果有矛盾或有未出现密文无法破译输出failed,否则输出明文。
思路:纯模拟题
T2:Hankson的趣味题
题目大意:给出a0,a1,b0,b1求满足条件的x的个数;
条件:gcd(x,a0)=a1;x,b0最小公倍数为b1;
思路:分解质因数,假设对于一个质因数y,a0含有a0c个y,a1含有a1c个y,b0含有b0c个y,b1含有b1c个y。
那么不难得到,如果a0c<a1c,那么就无解;如果a0c=a1c,那么x至少含有a1c个y;如果a0c>a1c,那么x只可能含有a1c个y。
同理,如果b1c<b0c,那么就无解;如果b1c=b0c,那么x至多含有b1c个y;如果b1c>b0c,那么x只可能含有b1c个y。
由此,可以求出对于每一个质数,x可能含有几个它,并求出一共有多少种选择方式。然后根据乘法原理,将每一个质数的选择方案数乘起来,就得到了答案。
----------------------------------------------------------
2017.5.6补充题解:
今天又做了一遍,然后对上面自己的做法一脸懵逼,估计是之前就没看懂吧然后贴了题解???
然后就各种焦虑,物色到了一个超级有道理的题解:
可以证明gcd(x/a1,a0/a1)==1,显然如果不等于1,则gcd(x,a0)<a1;
然后可以证明gcd(b1/x,b1/b0)==1,显然如果不等于1,则lcm(x,b0)<b1;
这样的话,显然就可以枚举b1的所有因数,sqrt(b1),加上gcd复杂度是logb1,所以单组数据复杂度是sqrt(b1)*log2(b1).
T3:最优贸易
题目大意:n个城市m条路,有单向和双向,水晶球在每个城市价格不同,求从城市1到n能获得的最大差价,每个城市可走多次。
思路,边数太多,所以用SPFA,正向做一次取最小,把路都反过来从n倒做一次取最大。在枚举i得到max(max[i]-min[i]);
AC代码:
#include <iostream> using namespace std; int num[]; int map[],nxt[]; int las; int head[]; int map2[],nxt2[]; int las2; int head2[]; void adad(int a,int b) { map[las]=b; nxt[las]=head[a]; head[a]=las++; } void adad2(int a,int b) { map2[las2]=b; nxt2[las2]=head2[a]; head2[a]=las2++; } #define Q_MAX 100000 int used[]; int queue[Q_MAX]; int h,r; void enq(int k) { if (used[k]) return; used[k]=; queue[r]=k; r=(r+)%Q_MAX; } int exq() { int t; t=queue[h]; used[t]=; h=(h+)%Q_MAX; return t; } int minn[]; int maxn[]; int main() { int i,j; int n,m; int a,b,c; cin >> n >> m; for (i=;i<n;i++) { head[i]=head2[i]=-; maxn[i]=-; minn[i]=0xFFFFFFF; cin >> num[i]; } for (i=;i<m;i++) { cin >> a >> b >> c; a--,b--; if (c==) { adad(a,b); adad(b,a); adad2(a,b); adad2(b,a); } else { adad(a,b); adad2(b,a); } } minn[]=num[]; enq(); while (h!=r) { i=exq(); for (a=head[i];a!=-;a=nxt[a]) { j=map[a]; if (minn[j]>minn[i]) { minn[j]=minn[i]; enq(j); } if (minn[j]>num[j]) { minn[j]=num[j]; enq(j); } } } maxn[n-]=num[n-]; enq(n-); while (h!=r) { i=exq(); for (a=head2[i];a!=-;a=nxt2[a]) { j=map2[a]; if (maxn[j]<maxn[i]) { maxn[j]=maxn[i]; enq(j); } if (maxn[j]<num[j]) { maxn[j]=num[j]; enq(j); } } } for (i=a=;i<n;i++) if (a<maxn[i]-minn[i]) a=maxn[i]-minn[i]; cout << a << "\n"; return ; }
T4:靶形数独
题目大意:解一个多解数独,从内向外分数不同,求分数最大的解法。
思路:解法肯定还是一样的,dfs。然后比较分数大小输出最大的。
然而这样会超时,codevs上可以过但是最慢的点用了2400多ms,时限4秒。
借鉴了一下某位神牛,用位运算加快运算速度(难写啊啊啊),试了一下还是能过的。
AC代码:
#include<iostream> #include<cmath> using namespace std; int h[]={},hs[]={},zs[]={},xj[][]={},hq[]={}; int ans=-,st[],a[][]; void make() { int i,j,sum=; for (i=;i<;i++) { for (j=i;j<-i;j++) sum+=(a[i][j]+a[-i][j])*(+i); for (j=i+;j<-i;j++) sum+=(a[j][i]+a[j][-i])*(+i); } sum+=a[][]*; if (sum>ans) ans=sum; } void dfs(int k) { if (k==) make(); else { int x,y,j,pos,p,i=st[k]; x=-h[i]; y=x&-x; h[i]|=y; j=(int)log2(y)+; pos=-(hs[i]|zs[j]|xj[(i-)/][(j-)/]); while (pos>) { p=pos&-pos; pos-=p; a[i][j]=(int)log2(p)+; hs[i]|=p; zs[j]|=p; xj[(i-)/][(j-)/]|=p; if (x==y) dfs(k+); else dfs(k); hs[i]-=p; zs[j]-=p; xj[(i-)/][(j-)/]-=p; } h[i]-=y; } } int main() { int i,j,p0; for (i=;i<;i++) for (j=;j<;j++) { cin >> a[i][j]; if (a[i][j]>) { h[i]|=<<(j-); p0=<<(a[i][j]-); if (((hs[i]&p0)!=)||((zs[j]&p0)!=)||((xj[(i-)/][(j-)/]&p0)!=)) { cout << "-1\n"; return ; } hs[i]|=p0; zs[j]|=p0; xj[(i-)/][(j-)/]|=p0; } else hq[i]++; } for (i=;i<;i++) st[i]=i; for (i=;i<;i++) for (j=i+;j<;j++) if (hq[st[i]]>hq[st[j]]) { st[i]^=st[j]; st[j]^=st[i]; st[i]^=st[j]; } i=; while (hq[st[i]]==) i++; dfs(i); cout << ans << "\n"; return ; }
noip2009提高组题解的更多相关文章
- noip2010提高组题解
NOIP2010提高组题解 T1:机器翻译 题目大意:顺序输入n个数,有一个队列容量为m,遇到未出现元素入队,求入队次数. AC做法:直接开1000的队列模拟过程. T2:乌龟棋 题目大意:有长度为n ...
- NOIP 2014 提高组 题解
NOIP 2014 提高组 题解 No 1. 生活大爆炸版石头剪刀布 http://www.luogu.org/problem/show?pid=1328 这是道大水题,我都在想怎么会有人错了,没算法 ...
- NOIP 2001 提高组 题解
NOIP 2001 提高组 题解 No 1. 一元三次方程求解 https://vijos.org/p/1116 看见有人认真推导了求解公式,然后猥琐暴力过的同学们在一边偷笑~~~ 数据小 暴力枚举即 ...
- NOIP 2000 提高组 题解
NOIP2000 提高组 题解 No 1. 进制转换 https://www.rqnoj.cn/problem/295 水题 对于n和基数r, 每次用n mod r, 把余数按照逆序排列 注意 mod ...
- 【NOIP2018】提高组题解
[NOIP2018]提高组题解 其实就是把写过的打个包而已 道路铺设 货币系统 赛道修建 旅行 咕咕咕 咕咕咕
- 洛谷 P1073 最优贸易 & [NOIP2009提高组](反向最短路)
传送门 解题思路 很长的题,实际上在一个有向图(点有点权)中求一个从起点1到终点n的路径,使得这条路径上点权最大的点与点权最小的点的差值最大(要求必须从点权较小的点能够走到点权较大的点). ——最短路 ...
- [NOIP2009] 提高组 洛谷P1073 最优贸易
题目描述 C 国有 n 个大城市和 m 条道路,每条道路连接这 n 个城市中的某两个城市.任意两个 城市之间最多只有一条道路直接相连.这 m 条道路中有一部分为单向通行的道路,一部分 为双向通行的道路 ...
- [NOIP2009] 提高组 洛谷P1071 潜伏者
题目描述 R 国和 S 国正陷入战火之中,双方都互派间谍,潜入对方内部,伺机行动.历尽艰险后,潜伏于 S 国的 R 国间谍小 C 终于摸清了 S 国军用密码的编码规则: 1. S 国军方内部欲发送的原 ...
- [NOIP2009] 提高组 洛谷P1074 靶形数独
题目描述 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他 们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z 博士请教, Z 博士拿出了他最近发明的 ...
随机推荐
- 设置ulimit值(Linux文件句柄数量)永久生效
Linux 默认打开文件数linux 默认打开文件数为1024个,通过ulimit -a 可以查看open files修改这个限制可以使用ulimt -SHn 65536永久生效需要进行下面设置:1. ...
- Linux进程内存分析pmap命令(转)
名称: pmap - report memory map of a process(查看进程的内存映像信息)用法 pmap [ -x | -d ] [ -q ] pids... ...
- ibatis CDATA
在使用ibatis时,经常需要配置待执行的sql语句.使用过ibatis的朋友都知道,无可避免的都会碰到一些不兼容.冲突的字符,多数人也都知道用<![CDATA[ ]]>标记避免Sql ...
- Top 6 Programming Languages for Mobile App Development
Mobile application development industry in the last five years have multiplied in leaps and bounds, ...
- __VA_ARGS__用法(转)
自定义调试信息的输出 调试信息的输出方法有很多种, 例如直接用printf, 或者出错时使用perror, fprintf等将信息直接打印到终端上, 在Qt上面一般使用qDebug,而守护进程则一 ...
- PLSQL_基础系列11_递归和层次查询CONNECT BY(案例)
2015-05-31 Created By BaoXinjian
- Idea KeyGen
import java.math.BigInteger; import java.util.Date; import java.util.Random; import java.util.Scanne ...
- STM32的串口
一:2个状态位_itstatus与_flagstatus的区别: _flagstatus:只是读状态标志,不管中断是否使能或发生.例如使用查询方式发送数据就需要读改状态位. _itstatus:和中断 ...
- vs2015-Azure Mobile Service
/App_Data /App_Start/ WebApiConfig.cs using System; using System.Collections.Generic; using System.C ...
- jdk与jre的区别
很多程序员已经干了一段时间java了依然不明白jdk与jre的区别.JDK就是Java Development Kit.简单的说JDK是面向开发人员使用的SDK,它提供了Java的开发环境和运行环境. ...