转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove
第二次周赛,由#84的div1以及#83的div2的AB组成
#83 div2 A 直接枚举,秒数+1
#83 div2 B 两个n位的二进制数相乘,结果最多为2*n位(二进制),根据这个,排序后判断
#84 div1 A 直接枚举,从少到多,枚举7的个数,7的个数越多,位数就越少,数字就越小。
结果显然是4在前,7在后
#84 div B
这题 有点蛋疼,我的做法是,首先预处理出所有的lucky number
然后开始枚举a[i],表示左端点要保存a[i]能取,但是a[i-1]不取,那么右端点就要保证b[i+k-1]能取,但是b[i+k]不能取
分别以A为左端点扫描一遍,B为左端点扫描一遍。
但是这样会忽视掉一种情况,就是K=1的情况,有可能左端点和右端点重合,如[4,4]刚好有一个lucky number。
所以要遍历一遍, 去重
int vl,vr,pl,pr,k; vector<int>a; void bfs() { queue<int>que; que.push(0); while(!que.empty()) { int u=que.front(); que.pop(); if(u>1e8) continue; int tmp=u*10+4; if(tmp>1e9||tmp<0) ;else {que.push(tmp);a.pb(tmp);} tmp=u*10+7; if(tmp>1e9||tmp<0) ;else {que.push(tmp);a.pb(tmp);} } } int main() { a.pb(0); bfs(); // for(int i=1;i<a.size();i++) printf("%d\n",a[i]); a.pb(1000000005); // freopen("1.in","r",stdin); while(scanf("%d%d%d%d%d",&vl,&vr,&pl,&pr,&k)!=EOF) { LL tot=(LL)(vr-vl+1)*(pr-pl+1); LL tmp=0,cnt=0; if(k==1) { for(int i=1;i<a.size()-1;i++) if(a[i]>=vl&&a[i]<=vr&&a[i]>=pl&&a[i]<=pr) cnt++; } for(int i=1;i<a.size()-k+1-1;i++) { if(a[i]<vl) continue; if(a[i-1]>=vr) continue; if(a[i+k-1]>pr) continue; if(a[i+k]<=pl) continue; tmp+=(LL)(min(vr,a[i])-max(a[i-1]+1,vl)+1)*(min(pr,a[i+k]-1)-max(pl,a[i+k-1])+1); } for(int i=1;i<a.size()-k+1-1;i++) { if(a[i]<pl) continue; if(a[i-1]>=pr) continue; if(a[i+k-1]>vr) continue; if(a[i+k]<=vl) continue; tmp+=(LL)(min(pr,a[i])-max(a[i-1]+1,pl)+1)*(min(vr,a[i+k]-1)-max(vl,a[i+k-1])+1); } printf("%.10f\n",(tmp-cnt)*1.0/tot); } return 0; }
一个树DP,处理从一个点出发,到达多少个点的路径中会出现Lucky nubmer。
果然tree_dp不是我的料,写得很渣。
以1为根,处理出所有子树的size
然后向下更新,表示从当前结点,往下遍历,会有多少个点的路径上出现lucky number。显然,如果当前路径便是lucky number,便直接加上size,否则加上孩子的down。
然后向上更新,表示从当前结点,往上遍历,会有多少个点的路径上出现lucky number。显然如果从父亲到当前节点的路径为Lucky number,便直接加上上面的所有节点数目,n-size[v]。否则便要算上父节点的向上更新以下,当前节点的所有兄弟结点(便是父亲的向下更新,减去当前的向下更新)
一般的一次DP就解决了,哎太弱了
struct Edge { int v,next; int f; }e[N]; int cnt=0,start[N],sz[N]; int down[N],up[N]; set<int>a; int n; void add(int u,int v,int f) { e[cnt].v=v;e[cnt].f=f;e[cnt].next=start[u]; start[u]=cnt++; e[cnt].v=u;e[cnt].f=f;e[cnt].next=start[v]; start[v]=cnt++; } void bfs() { queue<int>que; que.push(0); while(!que.empty()) { int u=que.front(); que.pop(); int tmp=u*10+4; if(tmp>1e9||tmp<0) ;else {que.push(tmp);a.insert(tmp);} tmp=u*10+7; if(tmp>1e9||tmp<0) ;else {que.push(tmp);a.insert(tmp);} } } void fuck1(int u,int pre) { sz[u]=1; for(int i=start[u];i!=-1;i=e[i].next) { int v=e[i].v; if(v==pre) continue; fuck1(v,u); sz[u]+=sz[v]; } } void fuck2(int u,int pre) { for(int i=start[u];i!=-1;i=e[i].next) { int f=e[i].f,v=e[i].v; if(v==pre) continue; fuck2(v,u); if(f) down[u]+=sz[v]; else down[u]+=down[v]; } } void fuck3(int u,int pre) { for(int i=start[u];i!=-1;i=e[i].next) { int v=e[i].v,f=e[i].f; if(v==pre) continue; if(f) up[v]+=n-sz[v]; else {up[v]+=up[u]; up[v]+=down[u]-down[v]; } fuck3(v,u); } } int main() { bfs(); mem(start,-1); scanf("%d",&n); mem(up,0);mem(down,0); for(int i=1;i<n;i++) { int f,u,v,w; scanf("%d%d%d",&u,&v,&w); if(a.find(w)==a.end()) f=0; else f=1; add(u,v,f); } fuck1(1,0); fuck2(1,0); fuck3(1,0); LL ans=0; for(int i=1;i<=n;i++) { ans+=(LL)(up[i]+down[i]-1)*(up[i]+down[i]); } printf("%I64d\n",ans); return 0; }
int check(int n) { while(n) { int t=n%10; if(t!=4&&t!=7) return 0; n/=10; } return 1; } int n,a[N]; int b[N]; //表示应该排在第i个位置的数现在的位置 int c[N]; //表示第i个数最终放在哪 vector<pair<int,int> >ans; bool cmp(int i,int j) { return a[i]<a[j]; } void slove(int &x,int y) { if(x==y) return; if(!check(a[x])&&!check(a[y])) puts("error"); swap(a[x],a[y]); ans.pb(mp(x,y)); swap(c[x],c[y]); b[c[x]]=x; b[c[y]]=y; x=y; } int main() { cin>>n; for(int i=1;i<=n;i++) cin>>a[i],b[i]=i; sort(b+1,b+1+n,cmp); int pos=-1; for(int i=1;i<=n;i++) c[b[i]]=i; for(int i=1;i<=n;i++) if(check(a[i])) {pos=i;break;} if(pos==-1) { int flag=1; for(int i=1;i<n;i++)if(a[i]>a[i+1]) flag=0; puts(flag?"0":"-1"); return 0; } for(int i=1;i<=n;i++) { // if(i!=pos) { slove(pos,i); slove(pos,b[i]); } } slove(pos,b[pos]); cout<<ans.size()<<endl; for(int i=0;i<ans.size();i++) cout<<ans[i].first<<" "<<ans[i].second<<endl; return 0; }