noip2012 day1
Vigenère密码
字符串的一个模拟,核心在于判断大小写(?)
#include<bits/stdc++.h> using namespace std; char k[10002],m[10002]; int main() { gets(k); gets(m); int l1=strlen(k); int l2=strlen(m); for(int i=0;i<l1;i++) { if(isupper(k[i])) k[i]=tolower(k[i]); } int j=0; for(int i=0;i<l2;i++) { if(islower(m[i])) { m[i]=char(m[i]-(k[j++]-'a')); if(m[i]<'a') m[i]=char(m[i]+26); } else { m[i]=char(m[i]-(k[j++]-'a')); if(m[i]<'A') m[i]=char(m[i]+26); } if(j>=l1) j=0; } printf("%s",m); }
国王游戏
贪心+高精度
首先,贪心策略:左右手乘积越小放越前面
策略证明:
a,b两人,左右手乘积为s,左手l,右手r
假设a在b前面比b在a前面更优
a在b前面时:
a所得为sa/la ……1'
b所得为sa*la*sb/rb ……2'
b在a前面时:
a所得为sb*lb*sa/ra ……3'
b所得为sb/lb ……4'
要使得假设成立,即:max(1',2')<max(3',4')
又显然,1'<3',2'<4'
所以化简即可得:la*ra<lb*rb
再在贪心基础上加上高精度就可以AC啦
但是高精度实在是难打啊,不打还能有60分,也是挺良心的
60分代码
#include <bits/stdc++.h> using namespace std; #define ll long long struct node { int x,y; }q[1003]; bool cmp(node aa, node bb) { return aa.x*aa.y<bb.x*bb.y; } int main() { int n,a,b; scanf("%d%d%d",&n,&a,&b); for(int i=1;i<=n;i++) { scanf("%d%d",&q[i].x,&q[i].y); } ll k=a; sort(q+1,q+n+1,cmp); ll ans=0; for(int i=1;i<=n;i++) { ans=max(ans,k/q[i].y); k*=q[i].x; } printf("%lld", ans); return 0; }
100分代码
#include<bits/stdc++.h> using namespace std; int now[20010],sum[20010],ans[20010],add[20010]; struct node { int x; int y; }q[10005]; void gjd1(int xx) { memset(add,0,sizeof(add)); for(int i=1;i<=ans[0];i++) { ans[i]=ans[i]*xx; add[i+1]+=ans[i]/10; ans[i]%=10; } for(int i=1;i<=ans[0]+4;i++) { ans[i]+=add[i]; if(ans[i]>=10) { ans[i+1]+=ans[i]/10; ans[i]%=10; } if(ans[i]!=0) { ans[0]=max(ans[0],i); } } return ; } int gjd2(int xx) { memset(add,0,sizeof(add)); int u=0; for(int i=ans[0];i>=1;i--) { u*=10; u+=ans[i]; add[i]=u/xx; if(add[0]==0&&add[i]!=0) { add[0]=i; } u%=xx; } return 0; } bool compare() { if(sum[0]==add[0]) { for(int i=add[0];i>=1;i--) { if(add[i]>sum[i]) return 1; if(add[i]<sum[i]) return 0; } } if(add[0]>sum[0]) return 1; if(add[0]<sum[0]) return 0; } bool cmp(node aa,node bb) { return aa.x*aa.y<bb.x*bb.y; } int main() { int n,a,b; scanf("%d%d%d",&n,&a,&b); for(int i=1;i<=n;i++) { scanf("%d%d",&q[i].x,&q[i].y); } sort(q+1,q+n+1,cmp); q[0].x=a,q[0].y=b; ans[0]=1,ans[1]=1; for(int i=1;i<=n;i++) { gjd1(q[i-1].x); gjd2(q[i].y); if(compare()) { for(int i=add[0];i>=0;i--) { sum[i]=add[i]; } } } for(int i=sum[0];i>=1;i--) printf("%d",sum[i]); return 0; }
开车旅行
倍增,但是预处理很麻烦
嗯还没打出来,留个坑,以后来填……