A题:Free Ice Cream
注意要使用LL,避免爆int
#include <bits/stdc++.h> #define scan(x,y) scanf("%d%d",&x,&y) using namespace std; typedef long long LL; const int Max=1e5+10; int main() { int n,has,x; while(~scan(n,has)) { LL have=has; char op;LL dis=0; for(int i=0;i<n;i++) { cin>>op>>x; if(op=='+') { have+=x; } else { if(have>=x) have-=x; else dis++; } } printf("%I64d %I64d ",have,dis); } }
B题:Little Robber Girl's Zoo
不要想得太复杂,直接暴力就好
#include <bits/stdc++.h> #define scan(x,y) scanf("%d%d",&x,&y) using namespace std; typedef long long LL; const int Max=1e3+10; int a[Max][Max],L[Max],R[Max],best[Max],l,r; int g=0,n; bool check() { int i=1,cnt=0,cunt=0; memset(L,0,sizeof(L));memset(R,0,sizeof(R)); while(i<n) { if(best[i]>best[i+1]) { cnt++; swap(best[i],best[i+1]); if(cnt==1) {L[cunt]=i;R[cunt++]=i+1;} else { if(i-1==R[cunt-1]) R[cunt-1]=i+1; else {L[cunt]=i;R[cunt++]=i+1;} } i+=2; } else { i++; } } if(cnt==0) return 1; for(int i=0;i<cunt;i++) printf("%d %d ",L[i],R[i]); return 0; } int main() { while(~scanf("%d",&n)) { g=0; for(int i=1;i<=n;i++) scanf("%d",&best[i]); memset(a,0,sizeof(a)); while(!check()); } return 0; }
C题:Robbers' watch
观察可知,由于时间表是7进制的,所以整个可行的序列长不会超过7位,因此可以套用数位dp的模式进行dfs搜索
#include <bits/stdc++.h> using namespace std; int ans,n,m; int vis[10]; int bit[2][111]; int pos[2]; stack<int>st1,st; void dfs2(int len,int flag,int id) { if(len==0) { ans++; return; } int end=flag?bit[id][len]:6; for(int i=0;i<=end;i++) { if(!vis[i]) { vis[i]=1; dfs2(len-1,i==end&&flag,id); vis[i]=0; } } } void dfs(int len,int flag,int id) { if(len==0) { if(id==1) dfs2(pos[0],1,0); return; } int end=flag?bit[id][len]:6; for(int i=0;i<=end;i++) { if(!vis[i]) { vis[i]=1; dfs(len-1,i==end&&flag,id); vis[i]=0; } } } int cacu(int x,int y) { pos[0]=0; bit[0][0]=bit[1][0]=0; if(x<7) bit[0][++pos[0]]=x; else { while(x) { bit[0][++pos[0]]=x%7; x/=7; } } pos[1]=0; if(y<7) bit[1][++pos[1]]=y; else { while(y) { bit[1][++pos[1]]=y%7; y/=7; } } if(pos[0]+pos[1]>10) return 0; else dfs(pos[1],1,1); return 1; } int main() { while(~scanf("%d%d",&n,&m)) { ans=0; n--;m--; printf("%d ",cacu(n,m)==0?0:ans); } return 0; }
D题:Kay and Snowflake
1.重心的另一个定义:以这个点为根,那么所有的子树(不算整个树自身)
的大小都不超过整个树大小的一半。(这个对解这道题很有用)
题解思路:
对于以u为根节点的子树,重心肯定在它的重儿子之中,但是有一个范围
可以想到重心的下区间是重儿子的重心,上区间就是u自己
可以对于这个范围内的节点,利用性质1逐个检测。
#include <bits/stdc++.h> using namespace std; const int Max=3e5+10; const int E=Max*2; int son[Max],maxson[Max],fa[Max],zx[Max]; int head[Max],nex[E],pnt[E],edge; void Init() { edge=0; memset(son,0,sizeof(son)); memset(maxson,0,sizeof(maxson)); memset(fa,-1,sizeof(fa)); memset(head,-1,sizeof(head)); } void Addedge(int u,int v) { pnt[edge]=v; nex[edge]=head[u]; head[u]=edge++; } void dfs1(int u) { son[u]=1; maxson[u]=0; int v; for(int e=head[u];e!=-1;e=nex[e]) { v=pnt[e]; dfs1(v); son[u]+=son[v]; maxson[u]=max(maxson[u],son[v]); } } bool is_ok(int u,int v) { if(son[u]>=maxson[v]*2&&son[u]>=(son[u]-son[v])*2) return 1; //利用定义4,检测是否是正确的重心,存在u自身的情况 //所以不能son[u]>=son[v]*2; return 0; } void dfs2(int u) { if(son[u]==1) { zx[u]=u; return; } int v,z=u; for(int e=head[u];e!=-1;e=nex[e]) { v=pnt[e]; dfs2(v); if(maxson[u]==son[v]) { z=zx[v]; } } while(!is_ok(u,z)&&fa[z]!=-1) { z=fa[z]; } zx[u]=z; } int main() { int n,m; while(~scanf("%d%d",&n,&m)) { Init(); int u,v; for(int i=2;i<=n;i++) { scanf("%d",&u); fa[i]=u; Addedge(u,i); } dfs1(1); dfs2(1); while(m--) { scanf("%d",&u); printf("%d ",zx[u]); } } return 0; }
E题:Optimal Point
题解链接:http://codeforces.com/blog/entry/45558
#include <bits/stdc++.h> using namespace std; #define MP(x,y) make_pair(x,y); typedef long long LL; const int Max=1e5+10; const LL inf=3*(LL)1e9*(LL)1e9+10; //(1e18不能直接写,会爆int) const LL LM=(LL(1)<<20)*(LL(1)<<20)*(LL(1)<<22)-1; const LL LMM=-(LL(1)<<20)*(LL(1)<<20)*(LL(1)<<23)+1; LL max(LL x,LL y){return x>=y?x:y;} LL min(LL x,LL y){return x<=y?x:y;} int n; struct coord{ LL x,y,z; coord(){}; coord(LL xx,LL yy,LL zz):x(xx),y(yy),z(zz){} }node[Max]; struct equa{ pair<LL,LL> s; pair<LL,LL> a; pair<LL,LL> b; pair<LL,LL> c; equa operator + (const equa e) { equa ans; ans.s=MP(max(s.first,e.s.first),min(s.second,e.s.second)); ans.a=MP(max(a.first,e.a.first),min(a.second,e.a.second)); ans.b=MP(max(b.first,e.b.first),min(b.second,e.b.second)); ans.c=MP(max(c.first,e.c.first),min(c.second,e.c.second)); return ans; } }; void Acc() { std::iostream::sync_with_stdio(false); cin.tie(NULL);cout.tie(NULL); } LL Getmid(LL x) { return (x-(x&1))/2; } struct coord Getsolu(const equa &x) { if(x.s.first>x.s.second|| x.a.first>x.a.second|| x.b.first>x.b.second|| x.c.first>x.c.second) return coord(LM,LM,LM); if(x.a.first+x.b.first+x.c.first>x.s.second|| x.a.second+x.b.second+x.c.second<x.s.first) return coord(LM,LM,LM); coord res; res.x=x.a.first; res.y=x.b.first; res.z=x.c.first; LL delta=max(LL(0),x.s.first-res.x-res.y-res.z); res.x+=min(delta,x.a.second-x.a.first); delta-=min(delta,x.a.second-x.a.first); res.y+=min(delta,x.b.second-x.b.first); delta-=min(delta,x.b.second-x.b.first); res.z+=min(delta,x.c.second-x.c.first); delta-=min(delta,x.c.second-x.c.first); assert(delta==0); return res; } struct coord Cacu(LL Maxlen) { //设Maxlen为最大距离 equa eq; eq.s=eq.a=eq.b=eq.c=MP(LMM,LM); for(int i=1;i<=n;i++) { equa ne; // -Maxlen<=A+B+C<=Maxlen // -Maxlen<=A<=Maxlen // -Maxlen<=B<=Maxlen // -Maxlen<=C<=Maxlen ne.s=MP(node[i].x+node[i].y+node[i].z-Maxlen, node[i].x+node[i].y+node[i].z+Maxlen); ne.a=MP(-node[i].x+node[i].y+node[i].z-Maxlen, -node[i].x+node[i].y+node[i].z+Maxlen); ne.b=MP(node[i].x-node[i].y+node[i].z-Maxlen, node[i].x-node[i].y+node[i].z+Maxlen); ne.c=MP(node[i].x+node[i].y-node[i].z-Maxlen, node[i].x+node[i].y-node[i].z+Maxlen); eq=eq+ne; //取最大距离 } for(LL r=0;r<=1;r++) { //对二取余,可能余1或者余0 equa tr=eq; tr.s.first=Getmid(tr.s.first-(3*r-1)); tr.a.first=Getmid(tr.a.first-(r-1)); tr.b.first=Getmid(tr.b.first-(r-1)); tr.c.first=Getmid(tr.c.first-(r-1)); tr.s.second=Getmid(tr.s.second-(3*r)); tr.a.second=Getmid(tr.a.second-(r)); tr.b.second=Getmid(tr.b.second-(r)); tr.c.second=Getmid(tr.c.second-(r)); coord solu=Getsolu(tr); if(solu.x!=LM) { coord ans; //(A,B奇偶性相同才会有整数解) ans.x=r+solu.y+solu.z; ans.y=r+solu.x+solu.z; ans.z=r+solu.x+solu.y; return ans; } } return coord(LM,LM,LM); //有超过Maxlen的距离或者无整数解 } int main() { Acc(); int T; for(cin>>T;T;T--) { cin>>n; for(int i=1;i<=n;i++) { cin>>node[i].x>>node[i].y>>node[i].z; } LL l=0,r=LM,answ=0; while(l<=r) { LL mid=l+(r-l)/2; if(Cacu(mid).x!=LM) r=mid-1,answ=mid; else l=mid+1; } coord ans=Cacu(answ); cout<<ans.x<<" "<<ans.y<<" "<<ans.z<<endl; } return 0; }