8月10号的练习:ZOJ 3203&&POJ 3974&&HDU 1394&&HDU 3400&&HDU 2152
2013-08-12 00:14
483 查看
Light Bulb ZOJ 3203
又是一道数学题:(三分法)
貌似不能二分角度!没有图不好说,具体参见:/article/2142175.html(里面有数学解法)
Palindrome POJ 3974
一道求最长回文子串:(必须是连续的)
就是用什么Manacher算法:
该算法的基本思路:
先是把原字符串扩大两倍:每隔一个插上‘#’,听说可以避免奇偶性的讨论。
之后还有一个剪枝问题:具体参见:http://www.2cto.com/kf/201210/164253.html
Minimum Inversion Number HDU 1394
一道线段树的问题,可以暴力也可树状数组:(由于精力有限,只用了线段数)
还是逆序数的问题:(这道不用离散化)
要得出答案主要是利用了一个结论:如果是0到n的排列,那么如果把第一个数放到最后,对于这个数列,逆序数是减少y[i],而增加n-1-y[i]的。(可以这样想,因为是第一个数,所有的数都在它后面,那么在当前位置pos比它大的数也在它后面,那么第一个数调到后面之后,在pos不成立的逆序数就成立了,所以多了n-y[i]-1,但是也少了在pos成立的逆序数,即y[i]个)
Line belt HDU 3400
三分题:(要进行两次三分求解)
之后是到母函数:可以说是模板题了。
Fruit HDU 2152
又是一道数学题:(三分法)
#include<iostream> #include<stdio.h> #include<algorithm> using namespace std; int main() { double H,h,D,l,r,mid,mmid; int n; scanf("%d",&n); while(n--) { scanf("%lf%lf%lf",&H,&h,&D); l=(H-h)*D/H; r=D;mid=0;mmid=0; while(r-l>1e-9) { mid=(l+r)/2; mmid=(mid+r)/2; if((mid+(H-h)*D/mid)>(mmid+(H-h)*D/mmid)) l=mid; else if((mid+(H-h)*D/mid)<(mmid+(H-h)*D/mmid)) r=mmid; else break; } printf("%.3lf\n",D+H-(l+(H-h)*D/l)); } return 0; }
貌似不能二分角度!没有图不好说,具体参见:/article/2142175.html(里面有数学解法)
Palindrome POJ 3974
一道求最长回文子串:(必须是连续的)
就是用什么Manacher算法:
#include<iostream> #include<stdio.h> #include<algorithm> #include<string.h> #include<string> using namespace std; char a[1000005],b[2000005]; int d[2000005]; int main() { int n,i,mia,ip,max1,d1=0; while(scanf("%s",a)!=EOF) { if(a[0]=='E') break; n=strlen(a); b[0]='@'; b[1]='#'; for(i=0;i<n;i++) { b[i*2+2]=a[i]; b[i*2+3]='#'; } b[2*n+2]='\0'; n=2*n+2; mia=0; ip=0; max1=1; for(i=0;i<n;i++) { if(mia>i) d[i]=min(d[2*ip-i],mia-i); else d[i]=1; for(;b[i-d[i]]==b[i+d[i]];d[i]++) if(i+d[i]>mia) { mia=i+d[i]; ip=i; } max1=max(max1,d[i]); } printf("Case %d: %d\n",++d1,max1-1); } return 0; }
该算法的基本思路:
先是把原字符串扩大两倍:每隔一个插上‘#’,听说可以避免奇偶性的讨论。
之后还有一个剪枝问题:具体参见:http://www.2cto.com/kf/201210/164253.html
Minimum Inversion Number HDU 1394
一道线段树的问题,可以暴力也可树状数组:(由于精力有限,只用了线段数)
还是逆序数的问题:(这道不用离散化)
#include<iostream> #include<stdio.h> #include<algorithm> using namespace std; struct line { int left; int right; int ma; }a[5005]; void build(int left,int right,int root) { a[root].left=left; a[root].right=right; a[root].ma=0; if(left==right) return ; build(left,(left+right)/2,2*root); build((left+right)/2+1,right,2*root+1); } void insert1(int x,int root) { if(x<a[root].left||x>a[root].right) return ; if(x==a[root].left&&x==a[root].right) { a[root].ma++;return ; } if(x>=a[root].left&&x<=a[root].right) a[root].ma++; insert1(x,2*root); insert1(x,2*root+1); } int find1(int left,int right,int root) { if(a[root].left>=left&&a[root].right<=right) return a[root].ma; if(a[root].left>right||left>a[root].right) return 0; return (find1(left,right,2*root)+find1(left,right,2*root+1)); } int main() { int sum,min1,n,i; int a1[5005]; while(scanf("%d",&n)!=EOF) { build(1,n,1); sum=0; for(i=1;i<=n;i++) { scanf("%d",&a1[i]); a1[i]++; insert1(a1[i],1); sum+=find1(a1[i]+1,n,1);//需要边更新,边求值 } min1=sum; for(i=1;i<=n-1;i++) { sum-=a1[i]-1; sum+=n-a1[i];//题目求的是最小值,每次把第一个数移到最后的最小值(逆序数的变化很明显) if(sum<min1) min1=sum; } printf("%d\n",min1); } return 0; }
要得出答案主要是利用了一个结论:如果是0到n的排列,那么如果把第一个数放到最后,对于这个数列,逆序数是减少y[i],而增加n-1-y[i]的。(可以这样想,因为是第一个数,所有的数都在它后面,那么在当前位置pos比它大的数也在它后面,那么第一个数调到后面之后,在pos不成立的逆序数就成立了,所以多了n-y[i]-1,但是也少了在pos成立的逆序数,即y[i]个)
Line belt HDU 3400
三分题:(要进行两次三分求解)
#include<stdio.h> #include<iostream> #include<math.h> #include<iostream> #include<algorithm> #include<string.h> using namespace std; struct point { double x,y; }; double dis(point a,point b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } double p,q,r; double find2(point a,point c,point d) { point left,right; point mid,midmid; double t1,t2; left=c; right=d; do { mid.x=(left.x+right.x)/2; mid.y=(left.y+right.y)/2; midmid.x=(mid.x+right.x)/2; midmid.y=(mid.y+right.y)/2; t1=dis(a,mid)/r+dis(mid,d)/q; t2=dis(a,midmid)/r+dis(midmid,d)/q; if(t1>t2) left=mid; else right=midmid; }while(dis(left,right)>=1e-9); return t1; } double find(point a,point b,point c,point d) { point left,right; point mid,midmid; double t1,t2; left=a; right=b; do { mid.x=(left.x+right.x)/2; mid.y=(left.y+right.y)/2; midmid.x=(mid.x+right.x)/2; midmid.y=(mid.y+right.y)/2; t1=dis(a,mid)/p+find2(mid,c,d); t2=dis(a,midmid)/p+find2(midmid,c,d); if(t1>t2) left=mid; else right=midmid; }while(dis(left,right)>=1e-9); return t1; } int main() { int T; point a,b,c,d; scanf("%d",&T); while(T--) { scanf("%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y); scanf("%lf%lf%lf%lf",&c.x,&c.y,&d.x,&d.y); scanf("%lf%lf%lf",&p,&q,&r); printf("%.2lf\n",find(a,b,c,d)); } return 0; }
之后是到母函数:可以说是模板题了。
Fruit HDU 2152
#include<iostream> #include<stdio.h> #include<algorithm> #include<string.h> using namespace std; int main() { int a[105],b[105]; int c1[10005],c2[10005]; int n,m,i,j,k; while(scanf("%d%d",&n,&m)!=EOF) { for(i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]); memset(c1,0,sizeof(c1)); memset(c2,0,sizeof(c2)); c1[0]=1; for(i=1;i<=n;i++) { for(j=0;j<=m;j++) for(k=a[i];k<=m&&k<=b[i];k++) c2[k+j]+=c1[j]; for(j=0;j<=m;j++) { c1[j]=c2[j]; c2[j]=0; } } printf("%d\n",c1[m]); } return 0; }
相关文章推荐
- POJ 2777 && ZOJ 1610 &&HDU 1698 --线段树--区间更新
- POJ 3652 & ZOJ 2934 & HDU 2721 Persistent Bits(数学 元)
- Hdu 1059 Dividing & Zoj 1149 & poj 1014 Dividing(多重背包)
- ZOJ 1103(POJ 2415)(HDU 1252)Hike…
- POJ 3654 & ZOJ 2936 & HDU 2723 Electronic Document Security(模拟)
- 8月14号的练习:HDU 1789&&HDU 1846&&HDU 1527&&POJ 1844&&HDU 1142
- POJ 3100 & ZOJ 2818 & HDU 2740 Root of the Problem(数学)
- 8月21号的练习:POJ 1511&&HDU 1018&&HDU 2571&&HDU 1533&&HDU 2554
- POJ 3100 & ZOJ 2818 & HDU 2740 Root of the Problem(数学)
- poj 1543 & HDU 1334 & ZOJ 1331 Perfect Cubes(数学 暴力大法好)
- zoj 1149 && hdu 1059 && poj 1014 Dividing
- POJ 3654 & ZOJ 2936 & HDU 2723 Electronic Document Security(模拟)
- HDU 1394&& ZOJ 1484 求最小的逆序数 (线段树)
- POJ 1071 & HDU 1364 & ZOJ 1019 Illusive Chase(DFS)
- hdu 4071& poj 3873 & zoj 3386 & uva 12197 Trick or Treat 三分法
- 8月13号的练习:POJ 3210&&HDU 4506&&HDU2546&&HDU 1026(注意事项)
- 8月11号的练习:POJ 3094&&HDU 1175&&HDU 2602&&HDU 2059
- 8月7号的练习:HDU 1069&&POJ 1636&&HDU 1031&&HDU 1051&&HDU 1551
- 计算几何基础与应用:HDU 1348&&ZOJ 1648&&POJ 2398&&ZOJ 1010
- POJ 3652 & ZOJ 2934 & HDU 2721 Persistent Bits(数学 进制)