NOIP2012提高组
D1T1.Vigenère密码
模拟
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
string a,b;cin>>b>>a;
for(int i=;i<a.size();i++)
{
bool ok=;if(a[i]>='a'&&a[i]<='z')a[i]=a[i]-'a'+'A',ok=;int j=i%b.size();
if(b[j]>='a'&&b[j]<='z')b[j]=b[j]-'a'+'A';
int c=((a[i]-'A')-(b[j]-'A')+)%;if(ok==)cout<<(char)(c+'A');else cout<<(char)(c+'a');
}
return ;
}
D1T2.国王游戏
贪心+高精度
我们知道,一个排序是经过好多次交换变成的,我们分析一下何时两个大臣需要交换,
设第一个大臣左右手数字为(a1,b1),第二个大臣左手数字为(a2,b2),第一个大臣前面的所有大臣和国王左手数字的乘积为x
那么交换前第一个大臣的奖赏为x/b1,第二个为(x*a1)/b2
交换后第一个大臣为x/b2,第二个为(x*a2)/b1
为了好看,我们设c1=x/b1,c2=(x*a1)/b2,c3=x/b2,c4=(x*a2)/b1
因为a>=1,b>=1,所以c4>=c1,c2>=c3
比较c2与c4的大小,可以发现,当a1/b2<a2/b1时,即a1*b1<a2*b2时,不交换是更优的,所以我们应该让a*b小的排在前面
记得写高精度!!!!!!!!!!!!!!!!!
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct HP{
int s,n[];
}aa[];
struct xxx{
int a,b;
}x[];
bool cmp(xxx a,xxx b)
{
return a.a*a.b<b.a*b.b;
}
void Max(HP a,HP b,HP &c)
{
memset(c.n,,sizeof(c.n));
if(a.s>b.s) c=a;
if(a.s<b.s) c=b;
if(a.s==b.s)
{
for(int i=a.s;i>=;i--)
{
if(a.n[i]>b.n[i]){c=a;break;}
if(a.n[i]<b.n[i]){c=b;break;}
}
if(c.s==)c=a;
}
}
void cheng(HP a,HP b,HP &c)
{
memset(c.n,,sizeof(c.n));
for(int i=;i<=a.s;i++)
for(int j=;j<=b.s;j++)
{
c.n[i+j-]+=(a.n[i]*b.n[j])%;
c.n[i+j]+=(a.n[i]*b.n[j])/;
}
if(c.n[a.s+b.s])c.s=a.s+b.s;
else c.s=a.s+b.s-;
}
void chu(HP a,int b,HP &c)
{
memset(c.n,,sizeof(c.n));
int now=;
for(int i=a.s;i>=;i--)
{
now+=a.n[i];c.n[i]=now/b;now=now%b*;
}
if(c.n[a.s])c.s=a.s;else c.s=a.s-;
}
int main()
{
int n;scanf("%d",&n);for(int i=;i<=n;i++)scanf("%d%d",&x[i].a,&x[i].b);
sort(x+,x+n+,cmp);
for(int i=;i<=n;i++)aa[i].n[]=x[i].a,aa[i].s=;
HP MAX,tot=aa[];chu(tot,x[].b,MAX);cheng(tot,aa[],tot);
for(int i=;i<=n;i++)
{
HP v;chu(tot,x[i].b,v);Max(v,MAX,MAX);cheng(tot,aa[i],tot);
}
int d[],dd=;
while(MAX.n[MAX.s])
{
d[++dd]=MAX.n[MAX.s]%;MAX.n[MAX.s]/=;
}
for(;dd;dd--)printf("%d",d[dd]);
for(int i=MAX.s-;i>=;i--)printf("%04d",MAX.n[i]);
return ;
}
D1T3.开车旅行
双向链表+倍增
先用双向链表求出每个点的小A和小B能到达的点,具体做法如下:
先排序,然后按数据在原数组的位置遍历,寻找每个数左边,左边的左边,右边,右边的右边的最小值和次小值
找完一个数,删一个数。把每个点小A开一次,小B开一次,算作一次
fa[i][j]表示从i点开2^j次到达的点,aa[i][j]表示从i点开2^j次小A开的距离,bb[i][j]表示从i点开2^j次小B开的距离
fa[i][j]=fa[fa[i][j-1]][j-1];
aa[i][j]=aa[i][j-1]+aa[fa[i][j-1]][j-1];
bb[i][j]=bb[i][j-1]+bb[fa[i][j-1]][j-1];
为了避免比值是double,所以a:b<c:d当ad<cb时,成立(c必须不等于0)
最后,如果ansb一直是0的话,应输出海拔最高的
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int a[],b[],n,m,x[],s[],bh[];
int fa[][];long long aa[][],bb[][];
struct xxx{
int h,lnext,rnext,no;
}data[];
bool cmp(xxx a,xxx b){return a.h<b.h;}
void gx(int _h,int _no,int h,int i,int &Min)
{
if(_h<=Min)
{
if(_h==Min)a[i]=_no;
else {a[i]=b[i];Min=_h;b[i]=_no;}
}
else if(abs(h-data[bh[a[i]]].h)>_h)a[i]=_no;
}
void ab()
{
data[].lnext=;data[].rnext=;data[].h=;
for(int i=;i<=n;i++)data[i].lnext=i-,data[i].rnext=i+;
data[n].rnext=;
for(int i=;i<=n;i++)
{
int Min=;
int no=data[bh[i]].no,h=data[bh[i]].h,l=data[bh[i]].lnext,r=data[bh[i]].rnext;
int l2h,l1h,r1h,r2h,l2no,l1no,r1no,r2no,l2,l1,r1,r2;
l1=data[l].lnext;l2=data[l1].lnext;
r1=data[r].rnext;r2=data[r1].rnext;
l1h=data[l].h;l2h=data[l1].h;
r1h=data[r].h;r2h=data[r1].h;
l1no=data[l].no;l2no=data[l1].no;
r1no=data[r].no;r2no=data[r1].no;
if(l1)gx(h-l2h,l2no,h,i,Min);
if(l)gx(h-l1h,l1no,h,i,Min);
if(r)gx(r1h-h,r1no,h,i,Min);
if(r1)gx(r2h-h,r2no,h,i,Min);
if(l)data[l].rnext=r;if(r)data[r].lnext=l;
}
}
void st()
{
for(int i=;i<=n;i++)
{
if(a[i])aa[i][]=abs(data[bh[i]].h-data[bh[a[i]]].h);
if(b[a[i]])bb[i][]=abs(data[bh[a[i]]].h-data[bh[b[a[i]]]].h);
fa[i][]=b[a[i]];
}
for(int j=;j<=;j++)
for(int i=;i<=n;i++)
{
fa[i][j]=fa[fa[i][j-]][j-];
aa[i][j]=aa[i][j-]+aa[fa[i][j-]][j-];
bb[i][j]=bb[i][j-]+bb[fa[i][j-]][j-];
}
}
void Ans(int u,int x,long long &ansa,long long &ansb)
{
for(int i=;i>=;i--)
{
if(fa[u][i]&&aa[u][i]+bb[u][i]<=x)
{
ansa+=aa[u][i],ansb+=bb[u][i];
x=x-aa[u][i]-bb[u][i];u=fa[u][i];
}
}
if(aa[u][]<=x)ansa+=aa[u][];
}
int main()
{
scanf("%d",&n);for(int i=;i<=n;i++){scanf("%d",&data[i].h);data[i].no=i;}
sort(data+,data+n+,cmp);for(int i=;i<=n;i++)bh[data[i].no]=i;
ab();st();int x;
scanf("%d%d",&x,&m);
long long ans=data[n].no,ansa=0ll,ansb=0ll;Ans(data[n].no,x,ansa,ansb);
for(int i=n-;i>=;i--)
{
int u=data[i].no;
long long aa=0ll,bb=0ll;Ans(u,x,aa,bb);
if(ansa==||aa*ansb<bb*ansa)ansa=aa,ansb=bb,ans=u;
}
if(ansb==)ans=data[n].no;
printf("%lld\n",ans);
for(int i=;i<=m;i++)
{
int s,x;scanf("%d%d",&s,&x);
long long aa=0ll,bb=0ll;Ans(s,x,aa,bb);
printf("%lld %lld\n",aa,bb);
}
return ;
}
D2T1.同余方程
ax ≡ 1 (mod b)意味着ax-by==1,求x
exgcd,ax-by==1可以看成ax+b(-y)==1
#include<iostream>
#include<cmath>
using namespace std;
int x,y;
void gcd(int a,int b)
{
if(b==){x=;y=;}
else
{
gcd(b,a%b);
int t=x;x=y;y=t-a/b*y;
}
}
int main()
{
int a,b;
cin>>a>>b;
gcd(a,b);
x=(x%b+b)%b;
cout<<x;
return ;
}
D2T2.借教室
二分+差分
由于剩余的教室是非递增的,所以我们可以二分答案
差分数组cf[]来差分r[]数组,cf[i]=r[i]-r[i-1]
每次租借s到t的d间教室,只要cf[s]-=d;cf[t+1]+=d;即可
然后还原原数组,如果剩余教室个数<0,就借不到这份订单,反之可以
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int cf[],n,m,d[],s[],t[],r[];
bool check(int ans)
{
for(int i=;i<=n+;i++)
{
cf[i]=r[i]-r[i-];
}
for(int i=;i<=ans;i++)
{
cf[s[i]]-=d[i];cf[t[i]+]+=d[i];
}
int last=;
for(int i=n;i>=;i--)
{
int x=last-cf[i+];last=x;if(x<)return false;
}
return true;
}
int main()
{
scanf("%d%d",&n,&m);for(int i=;i<=n;i++)scanf("%d",&r[i]);
for(int i=;i<=m;i++)scanf("%d%d%d",&d[i],&s[i],&t[i]);
int l=,r=m+,ans=;
while(l<r){
int mid=(l+r)/;
if(check(mid))l=mid+;
else ans=mid,r=mid;
}
if(ans==)cout<<;
else cout<<-<<endl<<ans;
return ;
}
NOIP2012提高组的更多相关文章
- 刷题总结——疫情控制(NOIP2012提高组)
题目: 题目背景 NOIP2012 提高组 DAY2 试题. 题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点. H 国的首都 ...
- GZOJ 1361. 国王游戏【NOIP2012提高组DAY1】
国王游戏[NOIP2012提高组DAY1] Time Limit:1000MS Memory Limit:128000K Description 国王游戏(game.cpp/c/pas) [问题描述] ...
- [NOIP2012] 提高组 洛谷P1081 开车旅行
题目描述 小 A 和小 B 决定利用假期外出旅行,他们将想去的城市从 1 到 N 编号,且编号较小的 城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i 的海拔高度为 Hi,城市 ...
- NOIP2012 提高组 Day 1
期望得分:100+100+70=270 实际得分:100+50+70=220 T2 没有底 最后剩余时间来不及打高精.思路出现错误 T1 Vigenère 密码 题目描述 16 世纪法国外交家 Bla ...
- [NOIP2012] 提高组 洛谷P1084 疫情控制
题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都, 也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控制疫情,不让疫情扩散 ...
- [NOIP2012] 提高组 洛谷P1080 国王游戏
题目描述 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右 手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n 位大臣排 成一排,国王站在队伍 ...
- [NOIP2012] 提高组 洛谷P1083 借教室
题目描述 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样. 面对海量租借教室的信息,我们自然 ...
- [NOIP2012] 提高组 洛谷P1082 同余方程
题目描述 求关于 x 的同余方程 ax ≡ 1 (mod b)的最小正整数解. 输入输出格式 输入格式: 输入只有一行,包含两个正整数 a, b,用一个空格隔开. 输出格式: 输出只有一行,包含一个正 ...
- [NOIP2012] 提高组 洛谷P1079 Vigenère 密码
题目描述 16 世纪法国外交家 Blaise de Vigenère 设计了一种多表密码加密算法――Vigenère 密 码.Vigenère 密码的加密解密算法简单易用,且破译难度比较高,曾在美国南 ...
- [NOIP2012提高组] CODEVS 1200 同余方程(扩展欧几里德算法)
数论题..所有数论对我来说都很恶心..不想再说什么了.. ------------------------------------------------ #include<iostream&g ...
随机推荐
- Educational Codeforces Round 37 E. Connected Components?(图论)
E. Connected Components? time limit per test 2 seconds memory limit per test 256 megabytes input sta ...
- c语言的左移、右移
先说左移,左移就是把一个数的所有位都向左移动若干位,在C中用<<运算符.例如: int i = 1; i = i << 2; //把i里的值左移2位 也就是说,1的2进制是0 ...
- 2 js的20/80关键知识
1. 2 var a = 1; undefined a 1 alert(a); undefined var b = true; var c = "Hi"; undefined al ...
- 安测云验证有CTA问题
背景: 现在所有的app 都需要通过工信部的审核.用户不同意之前,不能联网. 那么,我怎么知道自己的应用有没有联网呢?那么多sdk ,那么多代码?我怎么测试呢? 哈哈,我们测试给的方法真的很管用. l ...
- hadoop进阶
Java 多线程安全机制 1.操作系统有两个容易混淆的概念,进程和线程. 进程:一个计算机程序的运行实例,包含了需要执行的指令:有自己的独立地址空间,包含程序内容和数据:不同进程的地址空间是互相隔离的 ...
- @property后面可以有哪些修饰符?
原子性---nonatomic特质 如果不写默认情况为atomic(系统会自动加上同步锁,影响性能) 在iOS开发中尽量指定为nonatomic,这样有助于提高程序的性能 读/写权限---readwr ...
- maven的一些使用配置!
1.国外库太慢,更换为国内镜像库在你的maven安装目录下找到conf目录下的setting.xml修改:<mirrors> <id>CN</id> <nam ...
- python 多版本的兼容
1.针对linux版本 linux版本的话,首先调用whereis python 来获取到多版本的路径. root@Ulord-14:~# whereis pythonpython: /usr/bin ...
- CentOS 6.3下安装Vsftp,虚拟用户
CentOS 6.3下安装Vsftp,虚拟用户一.安装:1.安装Vsftpd服务相关部件:[root@linuxidc.com ~]# yum install vsftpd*Dependencies ...
- eclipse 运行错误:在类XXX中找不到 main 方法, 请将 main 方法定义为: public static void main(String[] args) 否则 JavaFX 应用程序类必须扩展javafx.application.Application
新建了一个类Hello: 代码: 第一次运行报错: 点击关闭该类的界面时出现: 点击是,然后再次打开,可以正确执行,结果为: 这是为什么....,后来发现了原因:是每次运行或调试前没有自动保存编辑的内 ...