第二周 9.6-9.12
9.6
FZU 1901 Period II
并不需要完整的周期。即最后一段可以不完整。
所以直接沿Next往后找就可以了。
行末不能有空格不然PE。
1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 # include <vector> 5 using namespace std; 6 int m,Next[1000100]; 7 char b[1000100]; 8 9 void getNext(void) 10 { 11 Next[0]=Next[1]=0; 12 for(int i=1;i<m;i++) 13 { 14 int j=Next[i]; 15 while(j&&b[i]!=b[j]) j=Next[j]; 16 Next[i+1]=b[i]==b[j]?j+1:0; 17 } 18 return; 19 } 20 21 int main(void) 22 { 23 int T; cin>>T; 24 for(int kase=1;kase<=T;kase++) 25 { 26 scanf("%s",b); 27 m=strlen(b); 28 getNext(); 29 vector<int> ans; 30 int pos=m; 31 while(pos) 32 { 33 pos=Next[pos]; 34 ans.push_back(pos); 35 } 36 printf("Case #%d: %d\n",kase,ans.size()); 37 for(int i=0;i<ans.size()-1;i++) printf("%d ",m-ans[i]); 38 printf("%d\n",m-ans[ans.size()-1]); 39 } 40 return 0; 41 }
HDU 5428 The Factor
应该不是第一次用这种方法。但是当时想不起来。
有一种拿到素数就想快筛的感觉。
感觉这种n^0.5的分解方法应该很常用。
1 # include <iostream> 2 # include <cstdio> 3 # include <algorithm> 4 using namespace std; 5 typedef long long LL; 6 int cnt; 7 8 struct node 9 { 10 int f,num; 11 } fac[2000]; 12 13 bool cmp(node x,node y) 14 { 15 return x.f<y.f; 16 } 17 18 int main(void) 19 { 20 int T;cin>>T; 21 while(T--) 22 { 23 int n; scanf("%d",&n); 24 cnt=0; 25 for(int i=0;i<n;i++) 26 { 27 int x; scanf("%d",&x); 28 for(LL j=2;j*j<=x;j++) if(x%j==0) 29 { 30 fac[cnt].f=j; 31 fac[cnt].num=0; 32 while(x%j==0){fac[cnt].num++;x/=j;} 33 cnt++; 34 } 35 if(x>1) 36 { 37 fac[cnt].f=x; 38 fac[cnt].num=1; 39 cnt++; 40 } 41 } 42 sort(fac,fac+cnt,cmp); 43 LL ans=1,tem=0; 44 for(int i=0;i<cnt;i++) 45 { 46 while(tem<2&&fac[i].num) 47 { 48 ans*=fac[i].f; 49 fac[i].num--; 50 tem++; 51 } 52 if(tem==2) break; 53 } 54 if(tem==2) printf("%I64d\n",ans); 55 else puts("-1"); 56 } 57 return 0; 58 }
9.7-9.8
什么都没干。
9.9
POJ 3613 Best Reward
做出manacher的p数组。扫一遍。
1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 # include <algorithm> 5 using namespace std; 6 const int maxn=500000+5; 7 int p[maxn*2],sum[maxn*2],alp[26]; 8 char o[maxn],s[maxn*2]; 9 10 int main(void) 11 { 12 int T ;cin>>T; 13 while(T--) 14 { 15 for(int i=0;i<26;i++) scanf("%d",alp+i); 16 scanf("%s",o+1); 17 int len=2*strlen(o+1)+1; 18 s[0]='$'; 19 for(int i=1;i<=len;i++) 20 { 21 if(i%2) s[i]='#'; 22 else s[i]=o[i/2]; 23 } 24 s[len+1]='^'; 25 int mx=0,id; 26 for(int i=1;i<=len;i++) 27 { 28 if(mx>i) p[i]=min(p[2*id-i],mx-i); 29 else p[i]=1; 30 while(s[i+p[i]]==s[i-p[i]]) p[i]++; 31 if(p[i]+i>mx) { mx=p[i]+i; id=i; } 32 } 33 for(int i=1;i<=len;i++) 34 { 35 if(s[i]=='#') sum[i]=sum[i-1]; 36 else sum[i]=sum[i-1]+alp[s[i]-'a']; 37 } 38 int ans=-2147483647; 39 for(int i=3;i<len-1;i+=2) 40 { 41 int tem=0,l=(1+i)/2,r=(i+len)/2; 42 if(l==p[l]) tem+=sum[i]-sum[0]; 43 if(len-r+1==p[r]) tem+=sum[len]-sum[i]; 44 ans=max(ans,tem); 45 } 46 printf("%d\n",ans); 47 } 48 return 0; 49 }
9.10-9.11
什么都没干。
9.12
打了个BC。
HDU 5432 Pyramid Split
简单二分。精度注意下QAQ。
1 # include <iostream> 2 # include <cstdio> 3 # include <cmath> 4 using namespace std; 5 int n,h[10001],b[10001]; 6 double V[10001],tot; 7 8 bool judge(double mid) 9 { 10 double sum=0; 11 for(int i=0;i<n;i++) 12 { 13 if(h[i]<mid) continue; 14 sum+=V[i]*pow(1-mid/h[i],3); 15 } 16 if(sum>tot/2) return false; 17 return true; 18 } 19 20 int main(void) 21 { 22 int T; cin>>T; 23 while(T--) 24 { 25 scanf("%d",&n); 26 for(int i=0;i<n;i++) scanf("%d",h+i); 27 for(int i=0;i<n;i++) scanf("%d",b+i); 28 for(int i=0;i<n;i++) V[i]=1.0*b[i]*b[i]*h[i]/3; 29 tot=0; 30 for(int i=0;i<n;i++) tot+=V[i]; 31 double l=0,r=1000,mid; 32 while(l<r-1e-9) 33 { 34 mid=(l+r)/2; 35 if(judge(mid)) r=mid; 36 else l=mid; 37 } 38 int ans=l; 39 printf("%d\n",ans); 40 } 41 return 0; 42 }
HDU 5433 Xiao Ming climbing
BFS。仅当有更优值时更新且入队。
状态开二维就够了。因为k是单调递减的。
如果某个点会被k更小时的更优解覆盖。那么在覆盖之前他的后继肯定已经用原值更新过一遍了。
如果后继也有更优也会自动覆盖。((描述不清楚。意会一下。
注意意志为0时走到也算失败QAQ。
1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 # include <algorithm> 5 # include <queue> 6 using namespace std; 7 typedef pair<int,int> pii; 8 int n,m,k,h[51][51],kk[51][51]; 9 int d[][2]={{1,0},{-1,0},{0,1},{0,-1}}; 10 bool vis[51][51]; 11 double e[51][51]; 12 queue<pii> q; 13 14 bool in(int i,int j) 15 { 16 return i>0&&i<=n&&j>0&&j<=m; 17 } 18 19 int main(void) 20 { 21 int T; cin>>T; 22 while(T--) 23 { 24 scanf("%d%d%d",&n,&m,&k); 25 for(int i=1;i<=n;i++) 26 { 27 char s[100]; scanf("%s",s); 28 for(int j=1;j<=m;j++) 29 { 30 if(s[j-1]=='#') h[i][j]=-1; 31 else h[i][j]=s[j-1]-'0'; 32 e[i][j]=-100; 33 } 34 } 35 int x1,y1,x2,y2; 36 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 37 memset(kk,-1,sizeof(kk)); 38 memset(vis,0,sizeof(vis)); 39 kk[x1][y1]=k; e[x1][y1]=0; 40 while(!q.empty()) q.pop(); 41 q.push(pii(x1,y1)); 42 while(!q.empty()) 43 { 44 pii now=q.front(); q.pop(); 45 int x=now.first,y=now.second; 46 vis[x][y]=0; 47 for(int i=0;i<4;i++) 48 { 49 int xx=x+d[i][0],yy=y+d[i][1]; 50 if(!in(xx,yy)||h[xx][yy]<0) continue; 51 double tem=e[x][y]+1.0*abs(h[x][y]-h[xx][yy])/kk[x][y]; 52 if(e[xx][yy]<-1||e[xx][yy]>tem) 53 { 54 e[xx][yy]=tem; 55 kk[xx][yy]=kk[x][y]-1; 56 if(kk[xx][yy]&&!vis[xx][yy]) 57 { 58 vis[xx][yy]=1; 59 q.push(pii(xx,yy)); 60 } 61 } 62 } 63 } 64 if(kk[x2][y2]>0) printf("%.2lf\n",e[x2][y2]); 65 else puts("No Answer"); 66 } 67 return 0; 68 }