matrix_world_final_2012
B http://acm.hust.edu.cn/vjudge/contest/view.action?cid=98759#problem/B
题意:瓶子侧躺在数轴上,瓶底在xlow,瓶口在xhigh,瓶身的曲线是多项式函数,给出a0--an是多项式系数,求瓶子的体积,和每增加 inc 体积的刻度值,最多输出8个。
解法:体积用积分求,刻度值用二分求。
1 //#define debug 2 //#define txtout 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cstring> 6 #include<cmath> 7 #include<cctype> 8 #include<ctime> 9 #include<iostream> 10 #include<algorithm> 11 #include<vector> 12 #include<queue> 13 #include<stack> 14 #include<map> 15 #include<set> 16 #define mt(a,b) memset(a,b,sizeof(a)) 17 using namespace std; 18 typedef long long LL; 19 const double eps=1e-8; 20 const double pi=acos(-1.0); 21 const int inf=0x3f3f3f3f; 22 const int M=1e5+10; 23 double a[M]; 24 double b[M]; 25 double xlow,xhigh,inc; 26 vector<double> answer; 27 int n; 28 void init_b(){ 29 for(int i=0;i<=n<<1;i++){ 30 b[i]=0; 31 } 32 for(int i=0;i<=n;i++){ 33 for(int j=0;j<=n;j++){ 34 b[i+j]+=a[i]*a[j]; 35 } 36 } 37 } 38 double f(double x){ 39 double sum=0; 40 for(int i=0;i<=n<<1;i++){ 41 sum+=b[i]*pow(x,i+1)/(i+1); 42 } 43 return sum*pi; 44 } 45 double get(double x2,double x1){ 46 return f(x2)-f(x1); 47 } 48 double solve(){ 49 init_b(); 50 return get(xhigh,xlow); 51 } 52 void solve_two(){ 53 answer.clear(); 54 for(int i=1;i<=8;i++){ 55 double L=xlow,R=xhigh; 56 if(get(R,L)<inc*i) return ; 57 while(L+eps<R){ 58 double mid=(L+R)*0.5; 59 if(get(mid,xlow)<inc*i){ 60 L=mid; 61 } 62 else{ 63 R=mid; 64 } 65 } 66 answer.push_back(L-xlow); 67 } 68 } 69 int main(){ 70 #ifdef txtout 71 freopen("in.txt","r",stdin); 72 freopen("out.txt","w",stdout); 73 #endif 74 int cas=1; 75 while(~scanf("%d",&n)){ 76 for(int i=0;i<=n;i++){ 77 scanf("%lf",&a[i]); 78 } 79 scanf("%lf%lf%lf",&xlow,&xhigh,&inc); 80 printf("Case %d: ",cas++); 81 double result=solve(); 82 printf("%.2f\n",result); 83 if(result<inc){ 84 puts("insufficient volume"); 85 continue; 86 } 87 solve_two(); 88 int len=answer.size(); 89 for(int i=0;i<len;i++){ 90 printf("%.2f%c",answer[i],i==len-1?'\n':' '); 91 } 92 } 93 return 0; 94 }
D http://acm.hust.edu.cn/vjudge/contest/view.action?cid=98759#problem/D
题意:定义斐波那契字符串 f0=“0” , f1=“1” ,fi = f i-1 + f i-2 。输入n和一个01串,问在第n个斐波那契字符串中出现了几次这个01串。
解法:对于比较小的串,可以把第n个斐波那契串直接处理出来,然后kmp。预处理到26个,就已经有190000长度了。对于大于26的串,答案有3部分,一部分等于fn-2中匹配成功的次数,一部分等于fn-1中匹配成功的次数,一部分等于fn-1的后缀加上fn-2的前缀在这个区间内匹配成功的次数。对于前两部分可以直接由之前的结果得到,对于中间的每次只保留len-1长度的前缀和后缀,这样不重不漏。
1 //#define debug 2 //#define txtout 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cstring> 6 #include<cmath> 7 #include<cctype> 8 #include<ctime> 9 #include<iostream> 10 #include<algorithm> 11 #include<vector> 12 #include<queue> 13 #include<stack> 14 #include<map> 15 #include<set> 16 #define mt(a,b) memset(a,b,sizeof(a)) 17 using namespace std; 18 typedef long long LL; 19 const double eps=1e-8; 20 const double pi=acos(-1.0); 21 const int inf=0x3f3f3f3f; 22 const int M=2e5+10; 23 struct G { 24 int len; 25 char str[M]; 26 } g[32]; 27 struct S{ 28 char prefix[M],suffix[M]; 29 }A,B,C; 30 char a[M]; 31 char buffer[M]; 32 int res[M]; 33 LL dp[128]; 34 int n; 35 class KMP { ///模式匹配(kmp)O(ls+lp) 36 typedef char typec;///文本元素的类型 37 static const int MV=1e6+10;///字符串的长度 38 int next[MV]; 39 public:///匹配串长度ls,str 存待匹配文本,模式串长度lp,pat 存模式串 40 int kmp(int ls,typec str[],int lp,typec pat[],int res[]) { ///返回匹配次数,res 中 41 // - 31 - 42 // 存储每个匹配的初始位置 43 int i=0,j=-1,cnt=0; 44 next[0]=-1; 45 while(i<lp) { 46 if(j==-1||pat[i]==pat[j]) { 47 next[++i]=++j; 48 continue; 49 } 50 j=next[j]; 51 } 52 i=j=0; 53 while(i<ls) { 54 while(j!=lp&&str[i]==pat[j]) { 55 i++; 56 j++; 57 } 58 if(!j) { 59 i++; 60 continue; 61 } 62 if(j==lp) { 63 res[cnt++]=i-j; 64 } 65 j=next[j]; 66 } 67 return cnt; 68 } 69 } gx; 70 void init() { 71 g[0].len=1; 72 strcpy(g[0].str,"0"); 73 g[1].len=1; 74 strcpy(g[1].str,"1"); 75 for(int i=2; i<=26; i++) { 76 g[i].len=g[i-1].len+g[i-2].len; 77 strcpy(g[i].str,g[i-1].str); 78 strcat(g[i].str,g[i-2].str); 79 } 80 } 81 int get_first_big_id(int len){ 82 for(int i=0;i<=26;i++){ 83 if(g[i].len>=len) return i; 84 } 85 } 86 void init_dp(int id,S &s){ 87 int la=strlen(a); 88 dp[id]=gx.kmp(g[id].len,g[id].str,la,a,res); 89 for(int i=0,j=g[id].len-la+1;i<la-1;i++,j++){ 90 s.prefix[i]=g[id].str[i]; 91 s.suffix[i]=g[id].str[j]; 92 } 93 s.prefix[la-1]=0; 94 s.suffix[la-1]=0; 95 } 96 LL solve() { 97 int la=strlen(a); 98 if(n<=26) { 99 return gx.kmp(g[n].len,g[n].str,la,a,res); 100 } 101 int id=get_first_big_id(la); 102 init_dp(id,A); 103 init_dp(id+1,B); 104 id+=2; 105 while(id<=n){ 106 dp[id]=dp[id-1]+dp[id-2]; 107 strcpy(buffer,B.suffix); 108 strcat(buffer,A.prefix); 109 dp[id]+=gx.kmp(strlen(buffer),buffer,la,a,res); 110 strcpy(C.prefix,B.prefix); 111 strcpy(C.suffix,A.suffix); 112 A=B; 113 B=C; 114 id++; 115 } 116 return dp[n]; 117 } 118 int main() { 119 #ifdef txtout 120 freopen("in.txt","r",stdin); 121 freopen("out.txt","w",stdout); 122 #endif 123 init(); 124 int cas=1; 125 while(~scanf("%d%s",&n,a)) { 126 printf("Case %d: %lld\n",cas++,solve()); 127 } 128 return 0; 129 }
end