ZOJ Monthly, June 2012
http://acm.zju.edu.cn/onlinejudge/showContestProblems.do?contestId=338
B题 我用的是二分 + 树状数组 ,x&(-x) 写成了 x&(-x)弄了半天
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; const int maxn=100010; #define lowbit(x) x&(-x) ll tab[maxn],num[maxn],op[maxn]; int Max,tot; char ord[maxn][10]; int cnt[maxn]; int bin1(ll key) { int l=1,r=Max,mid; while(l<=r) { mid=(l+r)>>1; if(tab[mid]==key) return mid; else if(tab[mid] > key) r=mid-1; else l=mid+1; } } void insert(int pos,int d) { for(int i=pos;i<=Max;i+=lowbit(i)) num[i]+=d; } int query(int pos) { int sum=0; for(int i=pos;i>0;i-=lowbit(i)) sum+=num[i]; return sum; } long long bin2(int s) { int l=1,r=Max,mid,ans=Max; while(l<=r) { mid=(l+r)>>1; int tmp=query(mid); if(tmp>=s) { ans=mid,r=mid-1; } else l=mid+1; } return tab[ans]; } int main() { int ca,n,k; scanf("%d",&ca); while(ca--) { scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%s %lld",ord[i],&op[i]); tab[i+1]=op[i]; } sort(tab+1,tab+n+1); Max=1; for(int i=2;i<=n;i++) if(tab[i]!=tab[i-1]) tab[++Max]=tab[i]; memset(num,0,sizeof(num)); memset(cnt,0,sizeof(cnt)); tot=0; //cout<< Max <<endl; for(int i=0;i<n;i++) { int pos=bin1(op[i]); //cout<<"bug" << pos <<" "<< query(pos) <<endl; if(ord[i][0]=='a') { tot++; insert(pos,1); cnt[pos]++; if(tot%2) { printf("%lld\n",bin2(tot/2+1)); } else { long long a=bin2(tot/2),b=bin2(tot/2+1); //cout<< a <<" "<< b<< " " << query(3)<<endl; if(((a+b)%2+2)%2==0) printf("%lld\n",(a+b)/2); else printf("%.1lf\n",(a+b)*1.0/2); } } else { int now=query(pos),pre=query(pos-1); //cout<< pre <<" "<<now<<endl; if(cnt[pos]==0) puts("Wrong!"); else { tot--; insert(pos,-1); cnt[pos]--; if(tot==0) puts("Empty!"); else { if(tot%2) { printf("%lld\n",bin2(tot/2+1)); } else { long long a=bin2(tot/2),b=bin2(tot/2+1); if(((a+b)%2+2)%2==0) printf("%lld\n",(a+b)/2); else printf("%.1lf\n",(a+b)*1.0/2); } } } } } } return 0; } /* 8 add 1 add 1 add 1 add 3 add 3 add 4 add 2 remove 2 */
J题 这个题很简单 ,很常见的状态压缩dp,d[state][node] 表示遍历了state 状态 到达node 节点所花费的最短时间
#include <iostream> #include <cstring> #include <cstdio> using namespace std; const int INF=100000000; int n,m,T; int value[10],start,end,dist[10][10]; int ans; int dp[1024][11]; void floyed() { /* for(int i=0;i<n;i++) for(int j=0;j<n;j++) dist[i][j]=map[i][j];*/ for(int i=0;i<n;i++) for(int j=0;j<n;j++) for(int k=0;k<n;k++) { dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]); } } int main() { int a,b,c; while(scanf("%d%d%d",&n,&m,&T)==3) { scanf("%d%d",&start,&end); for(int i=0;i<n;i++) scanf("%d",&value[i]); for(int i=0;i<n;i++) for(int j=0;j<n;j++) dist[i][j]=INF; for(int i=0;i<m;i++) { scanf("%d %d %d",&a,&b,&c); if(dist[a][b]>c) dist[a][b]=dist[b][a]=c; } for(int i=0;i<n;i++) dist[i][i]=0; floyed(); ans=0; for(int j=0;j<(1<<n);j++) for(int i=0;i<n;i++) dp[j][i]=INF; dp[1<<start][start]=0; int limit=1<<n; for(int i=0;i<limit;i++) for(int j=0;j<n;j++) if(dp[i][j]<=T) { for(int k=0;k<n;k++) dp[i|(1<<k)][k]=min(dp[i|(1<<k)][k],dp[i][j]+dist[j][k]); } //int ans for(int i=0;i<limit;i++) if(dp[i][end]<=T) { int sum=0; for(int j=0;j<n;j++) if(i&(1<<j)) sum+=value[j]; if(ans<sum) ans=sum; } printf("%d\n",ans); } return 0; }
#include <iostream> #include <vector> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef unsigned long long ll; const ll inf=1LL<<63; int a[110]; vector<pair<int,int> > e[110]; ll sum[110]; int main() { ll s; char str[110]; int k; for(int i=2;i<=62;i++){ if(a[i]==0){ e[i].push_back(make_pair(i,1)); for(int j=i*2;j<=62;j+=i){ a[j]=1; int t=j,cnt=0; while(t%i==0){ t/=i; cnt++; } e[j].push_back(make_pair(i,cnt)); } } } //for(int i=0;i<e[62].size();i++) // cout<< e[62][i].first<<" "<<e[62][i].second<<endl; while(cin>>str>>k) { int len=strlen(str); s=0;int p; for(int i=0;i<len;i++){ if('0'<=str[i]&&str[i]<='9') p=str[i]-'0'; else if('A'<=str[i]&&str[i]<='Z') p=str[i]-'A'+10; else if('a'<=str[i]&&str[i]<='z') p=str[i]-'a'+36; s=s*k+p; } //cout<< s <<endl; ll ans=inf; for(int i=0;i<e[k].size();i++) { int p=e[k][i].first; ll N=s,cnt=0; while(N) { cnt+=N/p; N/=p; } ans=min(ans,cnt/e[k][i].second); } cout<< ans <<endl; } return 0; }
#include <iostream> #include <cstdio> using namespace std; const int maxn=510; int n,m; double matrix[maxn][maxn],sum1[maxn][maxn],sum2[maxn][maxn]; double heig[maxn][maxn],heigh[maxn][maxn]; int que[maxn]; int main() { int Q,a,b,ca=1; while(scanf("%d %d",&n,&m)==2) { for(int i=0;i<n;i++) for(int j=0;j<m;j++) { scanf("%lf",&matrix[i][j]); sum1[i][j]=sum2[i][j]=0; } for(int i=0;i<n;i++) { double tot=0; for(int j=0;j<m;j++) { tot+=matrix[i][j]; sum1[i][j]= (i==0?0:sum1[i-1][j])+tot; } } for(int i=0;i<n;i++) { double tot=0; for(int j=0;j<m;j++) { tot+=matrix[i][j]*matrix[i][j]; sum2[i][j]=(i==0?0:sum2[i-1][j])+tot; } } // cout<<sum1[1][1]<<" "<<sum2[2][0]<<endl; printf("Case %d:\n",ca++); scanf("%d",&Q); double ans=99999999; int sx,sy; while(Q--) { scanf("%d %d",&a,&b); ans=99999999; for(int i=0;i<n;i++) { int l=0,r=-1; for(int j=0;j<m;j++) { while(l<=r&&matrix[i][que[r]] < matrix[i][j]) r--; que[++r]=j; if(j>=b-1) heig[i][j-b+1]=matrix[i][que[l]]; if(r-l+1>=b) l++; } } //cout<< heig[1][1] <<endl; for(int i=0;i<m;i++) { int l=0,r=-1; for(int j=0;j<n;j++) { while(l<=r&&heig[que[r]][i] < heig[j][i]) r--; que[++r]=j; if(j>=a-1) heigh[j-a+1][i]=heig[que[l]][i]; if(r-l+1>=a) l++; } } //cout<< heigh[2][3] <<endl; for(int i=0;i<=n-a;i++) for(int j=0;j<=m-b;j++) { double tmp1=(sum2[i+a-1][j+b-1]- (j==0?0:sum2[i+a-1][j-1]) - (i==0?0:sum2[i-1][j+b-1]) + ((i==0||j==0)?0:sum2[i-1][j-1]) -heigh[i][j]*heigh[i][j])/(a*b-1); double tmp2=(sum1[i+a-1][j+b-1]- (j==0?0:sum1[i+a-1][j-1]) - (i==0?0:sum1[i-1][j+b-1]) + ((i==0||j==0)?0:sum1[i-1][j-1])-heigh[i][j])/(a*b-1); tmp2*=tmp2; if(tmp1-tmp2 < ans) { ans=tmp1-tmp2; sx=i,sy=j; } else if(tmp1-tmp2 == ans&&sx>i) { // ans=tmp1-tmp2; sx=i,sy=j; } else if(tmp1-tmp2 == ans&&sx==i&&sy>j) { //ans=tmp1-tmp2; sx=i,sy=j; } } printf("(%d, %d), %.2lf\n",sx+1,sy+1,ans); } } return 0; }D 题终于知道错在哪里了,一个傻逼错误wa的我半死不活了,bug半天也没看出来,跟ac程序对拍才发现
if(r-l+1>=b) l++;写错了,看来模版题还是要多敲呀多记呀