【Noip2012】解题报告【字符】【贪心】【高精度】【倍增】【set】
目录:1:vigenere密码【字符】2:国王游戏【贪心】【高精度】3:开车旅行【倍增】【set】
题目:
VJ P1778 vigenere密码
描述
16世纪法国外交家Blaise de Vigenère设计了一种多表密码加密算法——Vigenère密码。Vigenère密码的加密解密算法简单易用,且破译难度比较高,曾在美国南北战争中为南军所广泛使用。
在密码学中,我们称需要加密的信息为明文,用M表示;称加密后的信息为密文,用C表示;而密钥是一种参数,是将明文转换为密文或将密文转换为明文的算法中输入的数据,记为k。 在Vigenère密码中,密钥k是一个字母串,k=k1k2…kn。当明文M=m1m2…mn时,得到的密文C=c1c2…cn,其中ci=(mi-'A'+ki-'A')mod26+'A',运算@的规则如下表所示:
例如,明文M= Helloworld 密钥 k=abc时, 密文 C=Hfnlpyosnd 。
明文 H e l l o w o r l d
密钥 a b c a b c a b c a
密文 H f n l p y o s n d
Vigenere加密在操作时需要注意:
1. @运算忽略参与运算的字母的大小写,并保持字母在明文M中的大小写形式;
2. 当明文M的长度大于密钥k的长度时,将密钥k重复使用。
格式
输入格式
输入共2行。
第一行为一个字符串,表示密钥k,长度不超过100,其中仅包含大小写字母。第二行为一个字符串,表示经加密后的密文,长度不超过1000,其中仅包含大小写字母。
输出格式
输出共1行,一个字符串,表示输入密钥和密文所对应的明文。
限制
每个测试点1s
提示
对于100%的数据,输入的密钥的长度不超过100,输入的密文的长度不超过1000,且都仅包含英文字母。
VJ P1779 国王游戏
描述
恰逢H国国庆,国王邀请n位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这n位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。
国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的位置始终在队伍的最前面。
格式
输入格式
第一行包含一个整数n,表示大臣的人数。
第二行包含两个整数a和b,之间用一个空格隔开,分别表示国王左手和右手上的整数。接下来n行,每行包含两个整数a和b,之间用一个空格隔开,分别表示每个大臣左手和右手上的整数。
输出格式
输出只有一行,包含一个整数,表示重新排列后的队伍中获奖赏最多的大臣所获得的金币数。
限制
每个测试点1s
提示
对于20%的数据,有1≤ n≤ 10,0 < a、b < 8;
对于40%的数据,有1≤ n≤20,0 < a、b < 8;
对于60%的数据,有1≤ n≤100;
对于60%的数据,保证答案不超过10^9;
对于100%的数据,有1 ≤ n ≤1,000,0 < a、b < 10000。
VJ P1780 开车旅行
描述
小A和小B决定利用假期外出旅行,他们将想去的城市从1到N编号,且编号较小的城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市i 的海拔高度为Hi,城市i 和城市j 之间的距离d[i,j]恰好是这两个城市海拔高度之差的绝对值,即d[i,j] = |Hi - Hj|。
旅行过程中,小A和小B轮流开车,第一天小A开车,之后每天轮换一次。他们计划选择一个城市S作为起点,一直向东行驶,并且最多行驶X公里就结束旅行。小A和小B的驾驶风格不同,小B总是沿着前进方向选择一个最近的城市作为目的地,而小A总是沿着前进方向选择第二近的城市作为目的地(注意:本题中如果当前城市到两个城市的距离相同,则认为离海拔低的那个城市更近)。如果其中任何一人无法按照自己的原则选择目的城市,或者到达目的地会使行驶的总距离超出X公里,他们就会结束旅行。
在启程之前,小A想知道两个问题:
1.对于一个给定的X=X0,从哪一个城市出发,小A开车行驶的路程总数与小B行驶的路程总数的比值最小(如果小B的行驶路程为0,此时的比值可视为无穷大,且两个无穷大视为相等)。如果从多个城市出发,小A开车行驶的路程总数与小B行驶的路程总数的比值都最小,则输出海拔最高的那个城市。
2. 对任意给定的X=Xi 和出发城市Si,小A开车行驶的路程总数以及小B行驶的路程总数。
格式
输入格式
第一行包含一个整数N,表示城市的数目。
第二行有N个整数,每两个整数之间用一个空格隔开,依次表示城市1到城市N的海拔高度,即H1,H2,……,Hn,且每个Hi 都是不同的。
第三行包含一个整数X0。
第四行为一个整数M,表示给定M组Si和Xi。
接下来的M行,每行包含2个整数Si 和Xi,表示从城市Si 出发,最多行驶Xi 公里。
输出格式
输出共M+1行。
第一行包含一个整数S0,表示对于给定的X0,从编号为S0的城市出发,小A开车行驶
的路程总数与小B行驶的路程总数的比值最小。
接下来的M行,每行包含2个整数,之间用一个空格隔开,依次表示在给定的Si 和Xi 下小A行驶的里程总数和小B行驶的里程总数。
样例2
限制
每个测试点1s
提示
对于30%的数据,有1≤N≤20,1≤M≤20;
对于40%的数据,有1≤N≤100,1≤M≤100;
对于50%的数据,有1≤N≤100,1≤M≤1,000;
对于70%的数据,有1≤N≤1,000,1≤M≤10,000;
对于100%的数据,有1≤N≤100,000,1≤M≤10,000,-1,000,000,000≤Hi≤1,000,000,000,0≤X0≤1,000,000,000,1≤Si≤N,0≤Xi≤1,000,000,000,数据保证Hi 互不相同。
题解:
第一题乍一看好像挺复杂的,但其实只要用ASCII码推出计算的公式,就简单多了,然后问题就只有字符处理和把大写字母转换成小/大写字母上了。
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
using namespace std;
char s1[],s2[],ans[];
bool pos[]={false};
int len1,len2;
int main()
{
freopen("vigenere.in","r",stdin);
freopen("vigenere.out","w",stdout);
cin>>s1;len1=strlen(s1);
cin>>s2;len2=strlen(s2);
for (int i=;i<len1;i++)
if (s1[i]<) s1[i]+=;//转化为小写字母
for (int i=;i<len2;i++)
if (s2[i]<)
{
pos[i]=true;//记录原来是大写字母的位置
s2[i]+=;
}
int t=;
while(t<len2)
{
int p=t;
while(p>=len1) p-=len1;//密文长度大于密匙
if(s2[t]<s1[p]) ans[t]=-s1[p]+s2[t];
//例如:s1='d' s2='a' ans=97+(122-s1)+(s2-91+1)=123-s1+s2=120='x'
else if (s2[t]==s1[p]) ans[t]='a';
else ans[t]=+s2[t]-s1[p];
if (pos[t]) ans[t]-=;//如果原为大写字母则复原
t++;
}
for (int i=;i<len2;i++)
cout<<ans[i];
return ;
}
第二题显然不能找排列方式一一判断。方法:如果要交换A大臣和B 大臣,需要满足的是:L(A)/R(B)>L(B)/R(A),即L(A)*R(A)>L(B)*R(B).所以按照这个规则排序再找最大值就是ans。
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,v,e;
struct pp{
int l,r,k;
};
pp que[];
const int/**/ comp(const pp &x,const pp &y)
{
return x.k<y.k;
}
struct hp{
int w[];
};
hp ans,sum;
hp cheng (hp a,int b)
{
hp c;
c.w[]=a.w[]+;
for (int i=;i<=c.w[];i++) c.w[i]=;
for (int i=;i<=c.w[];i++)
{
c.w[i]+=a.w[i]*b;
c.w[i+]+=c.w[i]/;
c.w[i]%=;
}
while (c.w[]>&&c.w[c.w[]]==) c.w[]--;
return c;
}
hp chu(hp a,int b)
{
hp c;
c.w[]=a.w[]+;
for (int i=;i<=c.w[];i++) c.w[i]=;
int x=;
for (int i=a.w[];i>=;i--)
{
x=x*+a.w[i];
c.w[i]=x/b;
x%=b;
}
while(c.w[]>&&c.w[c.w[]]==) c.w[]--;
return c;
}
hp bj(hp a,hp b)
{
if (a.w[]>b.w[]) return a;
if (a.w[]<b.w[]) return b;
for (int i=a.w[];i>=;i--)
{
if (a.w[i]>b.w[i]) return a;
if (a.w[i]<b.w[i]) return b;
}
return a;
}
int main()
{
freopen("game.in","r",stdin);
freopen("game.out","w",stdout);
cin>>n;
cin>>v>>e;
for (int i=;i<=n+;i++)
{
scanf("%d%d",&que[i].l,&que[i].r);
que[i].k=que[i].l*que[i].r;
}
sort(que+,que++n,comp);
sum.w[]=;
sum.w[]=v;
for (int i=;i<=n;i++)
{
ans=bj(ans,chu(sum,que[i].r));
sum=cheng(sum,que[i].l);
}
printf("%d",ans.w[ans.w[]]);
for (int i=ans.w[]-;i>=;i--) printf("%04d",ans.w[i]);
return ;
}
第三题如果纯模拟并且初始了第一第二近的城市可以过70。满分是用 set初始+倍增过程。具体做法解释可以参照http://blog.csdn.net/nilihan1999/article/details/37809903
#include<iostream>
#include<cstdio>
#include<set>
#include<algorithm>
#include<cmath>
#define LL long long
#ifdef WIN32
#define AUTO "%I64d %I64d\n"
#else
#define AUTO "%lld %lld\n"
#endif
using namespace std;
const int maxn=;
struct pp{
int h,num;
bool operator < (const pp rr) const
{
return h<rr.h;
}
};
pp city[maxn];
set<pp> s;
set<pp>::iterator it;
int n,m,x0;
int to[maxn][],dis[maxn][],g[maxn][];
LL f[maxn][][];//0:B 1:A
void find_near(pp x,pp y)
{
int d=abs(x.h-y.h);
if (!to[x.num][])
{
to[x.num][]=y.num;
dis[x.num][]=d;
}
else if (d<dis[x.num][]||(d==dis[x.num][]&&y.h<city[to[x.num][]].h))
{
to[x.num][]=to[x.num][];
dis[x.num][]=dis[x.num][];
dis[x.num][]=d;
to[x.num][]=y.num;
}
else if (d<dis[x.num][]||(d==dis[x.num][]&&y.h<city[to[x.num][]].h))
{
to[x.num][]=y.num;
dis[x.num][]=d;
}
else if (!to[x.num][])
{
to[x.num][]=y.num;
dis[x.num][]=d;
}
return ;
}
void find_way()
{
for (int i=n;i>=;i--)
{
s.insert(city[i]);
it=s.find(city[i]);
if (it!=s.begin())
{
it--;
find_near(city[i],*it);
if (it!=s.begin())
{
it--;
find_near(city[i],*it);
it++;
}
it++;
}
if ((++it)!=s.end())
{
find_near(city[i],*it);
if ((++it)!=s.end())
{
find_near(city[i],*it);
it--;
}
it--;
}
}
}
void begin()
{
for (int i=;i<=n;i++)
{
g[i][]=to[to[i][]][];
f[i][][]=dis[i][];
f[i][][]=dis[to[i][]][];
}
for (int j=;j<=;j++)
for (int i=;i<=n;i++)
{
g[i][j]=g[g[i][j-]][j-];
f[i][j][]=f[i][j-][]+f[g[i][j-]][j-][];
f[i][j][]=f[i][j-][]+f[g[i][j-]][j-][];
}
}
void query(int s,int x,LL &disa,LL &disb)
{
for (int i=;i>=;i--)// >= 0
if (f[s][i][]+f[s][i][]<=x&&g[s][i])
{
disa+=f[s][i][];
disb+=f[s][i][];
x-=f[s][i][]+f[s][i][];
s=g[s][i];
}
if (to[s][]&&dis[s][]<=x)
disa+=dis[s][];
}
int main()
{
freopen("drive.in","r",stdin);
freopen("drive.out","w",stdout);
cin>>n;
for (int i=;i<=n;i++)
{
scanf("%d",&city[i].h);
city[i].num=i;
}
find_way();
begin();
cin>>x0;
LL a=,b=;
int ans=;
for (int i=;i<=n;i++)
{
LL disa=,disb=;
query(i,x0,disa,disb);
if (disb!=&&(!ans||a*disb>b*disa))
{
a=disa;
b=disb;
ans=i;
}
}
cout<<ans<<endl;
cin>>m;
for (int i=;i<=m;i++)
{
int s,x;
LL disa=,disb=;
scanf("%d%d",&s,&x);
query(s,x,disa,disb);
printf(AUTO,disa,disb);
}
return ;
}
这毕竟是放了一个月暑假返校后的第一次测试,暑假本来计划的一切都没有完成,什么刷题啊、复习啊..既然荒废了一个月,那么再联赛前的这两个多月里,就要更加努力了。
这次考试分数太差,第一题把'A'放在s1==s2的情况,又多剪了一个32,导致所有A都输成了'!'。。
第二题直接用L(i)排序去了,只过了30。
第三题到考试结束时还没有调出来,所以。。
总结:要加快做题速度,加强算法练习,注意小问题。
【Noip2012】解题报告【字符】【贪心】【高精度】【倍增】【set】的更多相关文章
- NOIP2012 解题报告
TG Day1 T3 开车旅行 1. 预处理出从每座城市两人分别会到达的两座城市. 用 set 可以轻松实现. 2. 用倍增优化 DP 令 \(f_{i,j,k}\) 表示从城市 \(j\) 出发,行 ...
- poj1328解题报告(贪心、线段交集)
POJ 1328,题目链接http://poj.org/problem?id=1328 题意: 有一海岸线(x轴),一半是陆地(y<0).一半是海(y>0),海上有一些小岛(用坐标点表示P ...
- [Codeforces 911F] Tree Destruction 解题报告(贪心)
题目链接: http://codeforces.com/contest/911/problem/F 题目大意: 给你一棵树,每次挑选这棵树的两个度数为1的点,加上他们之间的边数(距离),然后将其中一个 ...
- [jzoj 4879] [NOIP2016提高A组集训第11场11.9] 少女觉 解题报告 (贪心)
题目链接: http://172.16.0.132/senior/#main/show/4879 题目: 在幽暗的地灵殿中,居住着一位少女,名为古明地觉.据说,从来没有人敢踏入过那座地灵殿,因为人们恐 ...
- [luogu P2123] 皇后游戏 解题报告(贪心)
题目链接:https://www.luogu.org/problemnew/show/P2123 题目大意: 给定a数组和b数组,要求最小化c数组中的最大值 题解: 考虑微扰法,推一波式子先 设$x= ...
- 【未完成0.0】Noip2012提高组day2 解题报告
第一次写一套题的解题报告,感觉会比较长.(更新中Loading....):) 题目: 第一题:同余方程 描述 求关于x的同余方程ax ≡ 1 (mod b)的最小正整数解. 格式 输入格式 输入只有一 ...
- Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增)
Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增) Description H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树, 1 号城市是首都, 也是 ...
- 【剑指Offer】第一个只出现一次的字符 解题报告(Python)
[剑指Offer]第一个只出现一次的字符 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-intervie ...
- 【剑指Offer】字符流中第一个不重复的字符 解题报告(Python)
[剑指Offer]字符流中第一个不重复的字符 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interv ...
- NOIP2012普及组 (四年后的)解题报告 -SilverN
本章施工仍未完成 现在的时间是3.17 0:28,我困得要死 本来今天(昨天?)晚上的计划是把整个四道题的题解写出来,但是到现在还没写完T4的高效算法,简直悲伤. 尝试了用floyd写T4,终于大功告 ...
随机推荐
- TCP拥塞控制
TCP必须使用端到端拥塞控制而不是使网络辅助的拥塞控制,因为IP层不向端系统提供显式的网络拥塞反馈.TCP采用的方法是让每一个发送方根据所感知到的网络拥塞程度来限制其能向连接发送流量的速率. 几个相关 ...
- 动画Animation
动画分类:Animation 单一动画 AnimationSet 复合动画 AnimationSet是Animation的实现子类,Animation是一个抽象类,他的实现子类主要有如下几种: 主要有 ...
- require 和 file_get_contents
requirerequire_onceincludeinclude_oncecurlfile_get_contents---各种选择的比较 还有这么复杂的说法,怎么办? 在开发过程中发现,用requi ...
- android优化从网络中加载图片速度。。
从网络中加载图片主要要注意两个方面的问题: 1.内存管理:图片占的内存很大,假如图片数量多,很容易让系统抛出out of memory的异常. 同时我们也要注意不同android版本中内存管理的区别. ...
- webstorm搭建node服务器
前言,搭建服务器,必须有node.js环境(吐槽:本来就是用node搭建的(⊙o⊙)…) 下载node.js 网址 https://nodejs.org/en/ 先新建项目: 这里选择Node.js ...
- Qt之QSS(白色靓丽)
简述 Qt助手中有关于各种部件的QSS详细讲解,资源很丰富,请参考:Qt Style Sheets Examples. 白色靓丽 - 一款漂亮的QSS风格. 你可以直接使用,也可以随意转载,但请务必保 ...
- 如何使用java调用DLL运行C++(初篇)
JNI:Java Native Interface,简称JNI,是Java平台的一部分,可用于让Java和其他语言编写的代码进行交互. 下面是从网上摘取的JNI工作示意图:
- ajax接触
1. function doSave() { ajax_get("${contextPath}/auth/functionsave", $("#editForm" ...
- 手把手教你如何搭建iOS项目基本框架
手把手教你如何搭建iOS项目基本框架 今天我们来谈谈如何搭建框架,框架需要做一些什么. 第一步:找到我们的目标我们的目标是让其他开发人员拿到手后即可写页面,不再需要考虑其他的问题. 第二步:我们需要做 ...
- Stylus Studio的安装与卸载