您的位置:首页 > 理论基础 > 计算机网络

2012金华网络赛赛后【缺ABC】

2012-10-03 03:41 465 查看
A Mines (HDU
4400)

B Battery (HDU
4401)

C Magic Board (HDU
4402)

D A very hard Aoshu problem (HDU
4403)

枚举“=”的位置,分别对左右两部分进行DFS,统计出相等的个数即可:
#include<map>
#include<cstdio>
#include<cstring>
using namespace std;
map<int,int>mp;
char s[100];
int len,ans;
void dfs(int pre,int tmp,int l,int r,bool fg)
{
if(l==r)
{
if(fg) ans+=mp[pre+tmp];
else mp[pre+tmp]++;
return;
}
dfs(pre+tmp,s[l]-48,l+1,r,fg);
dfs(pre,tmp*10+s[l]-48,l+1,r,fg);
}
int main()
{
while(scanf("%s",s),strcmp(s,"END"))
{
len=strlen(s),ans=0;
for(int i=1;i<len;i++)
{
mp.clear();
dfs(0,0,0,i,0);
dfs(0,0,i,len,1);
}
printf("%d\n",ans/4);
}
return 0;
}


E Worms (HDU
4404)

计算几何,多边形与圆交模板题
#include<cmath>
#include<vector>
#include<cstdio>
#include<algorithm>
using namespace std;
#define sqr(x) ((x)*(x))

const int N=1010;
const double pi=acos(-1.0);

int n;
double r;

struct cpoint
{
double x,y;
cpoint(){}
cpoint(double x,double y):x(x),y(y){}
}pin
;

int dcmp(double x){return (x>1e-8)-(x<-1e-8);}

void cal(cpoint u,cpoint v,double r,vector<cpoint>&ret)
{
ret.push_back(u);
double a=sqr(v.x-u.x)+sqr(v.y-u.y);
double b=2*((v.x-u.x)*u.x+(v.y-u.y)*u.y);
double c=sqr(u.x)+sqr(u.y)-r*r;
double d=b*b-4*a*c;
if(d<0) return;
d=sqrt(d);
double t1=(-b+d)/(2*a),t2=(-b-d)/(2*a);
if(t1>t2) swap(t1,t2);
if(dcmp(t1)>0&&dcmp(1-t1)>0)
ret.push_back(cpoint(u.x+(v.x-u.x)*t1,u.y+(v.y-u.y)*t1));
if(dcmp(t2)>0&&dcmp(1-t2)>0&&dcmp(t2-t1)>0)
ret.push_back(cpoint(u.x+(v.x-u.x)*t2,u.y+(v.y-u.y)*t2));
}

double tri(const cpoint &u,const cpoint &v){return u.x*v.y-u.y*v.x;}

double arc(const cpoint &u,const cpoint &v,double r)
{
double t=atan2(v.y,v.x)-atan2(u.y,u.x);
while(t> pi) t-=2*pi;
while(t<-pi) t+=2*pi;
return r*r*t;
}

double area(double r,cpoint pin[],int n)
{
double ans=0;pin
=pin[0];
vector<cpoint>v;
for(int i=0;i<n;i++) cal(pin[i],pin[i+1],r,v);
v.push_back(v.front());
for(int i=1;i<v.size();i++)
{
if(sqrt(sqr((v[i-1].x+v[i].x)/2)+sqr((v[i-1].y+v[i].y)/2))<r) ans+=tri(v[i-1],v[i]);
else ans+=arc(v[i-1],v[i],r);
}
return fabs(ans/2);
}

int main()
{
double x,y,v,e,t,g,r;
while(scanf("%lf%lf%lf%lf%lf%lf%lf",&x,&y,&v,&e,&t,&g,&r),dcmp(x+y+v+e+t+g+r))
{
scanf("%d",&n);
x+=v*cos(e/180*pi)*t;
y+=v*sin(e/180*pi)*t-g*t*t/2;
for(int i=0;i<n;i++)
{
scanf("%lf%lf",&pin[i].x,&pin[i].y);
pin[i].x-=x,pin[i].y-=y;
}
printf("%.2f\n",area(r,pin,n));
}
return 0;
}


F Aeroplane chess (HDU
4405)

。。。
#include<cstdio>
#include<cstring>

const int N=100010;

double dp
;
int nxt
;

int main()
{
int n,m,u,v;
while(scanf("%d%d",&n,&m),n||m)
{
memset(dp,0,sizeof(dp));
memset(nxt,-1,sizeof(nxt));
for(int i=0;i<m;i++) scanf("%d%d",&u,&v),nxt[u]=v;
for(int i=n-1;i>=0;i--) for(int j=1;j<=6;j++)
{
int k=i+j;
while(~nxt[k]) k=nxt[k];
dp[i]+=(dp[k]+1)/6;
}
printf("%.4f\n",dp[0]);
}
return 0;
}


G GPA (HDU
4406)

最大费用最大流。s到每门课连一条边(k,0),每门课与每天之间按01矩阵连边,每门课与t之间建边:x<60,建(60-x,lim),k+=60-x,x~100,分别建一条(1,g(x+1)-g(x))的边。统计出g(x0)之和+最大费用-k*lim即为最终gpa.
#include<cstdio>
#include<cstring>

typedef long long ll;
const ll inf=0x3f3f3f3f3f3f3f3fll;
const int N=110,M=100010;
#define min(a,b) ((a)<(b)?(a):(b))

struct MaxCostMaxFlow
{
int e,ev[M],nxt[M],head[M];
ll cost[M],dis[M],cap[M];
int pnt
,road
,q
,bg,ed;
bool vis
;
void init(){e=0;memset(head,-1,sizeof(head));}
void add(int u,int v,ll f,ll c)
{
ev[e]=v;cap[e]=f;cost[e]= c;nxt[e]=head[u];head[u]=e++;
ev[e]=u;cap[e]=0;cost[e]=-c;nxt[e]=head[v];head[v]=e++;
}
bool spfa(int s,int t,int n)
{
for(int i=0;i<n;i++) dis[i]=-1,vis[i]=0;
bg=ed=dis[s]=0;
pnt[s]=s;q[ed++]=s;
while(bg!=ed)
{
int u=q[bg++];vis[u]=0;
if(bg==n) bg=0;
for(int i=head[u];~i;i=nxt[i])
{
if(cap[i]<=0)continue;
ll v=ev[i];
if(dis[v]<dis[u]+cost[i])
{
dis[v]=dis[u]+cost[i];
pnt[v]=u;road[v]=i;
if(!vis[v]) q[ed++]=v;
vis[v]=1;
if(ed==n) ed=0;
}
}
}
return dis[t]!=-1;
}
ll maxcost(int s,int t,int n)
{
ll c=0,f=0;
while(spfa(s,t,n))
{
ll minf=inf;
for(int u=t;u!=s;u=pnt[u]) minf=min(minf,cap[road[u]]);
for(int u=t;u!=s;u=pnt[u]) cap[road[u]]-=minf,cap[road[u]^1]+=minf;
f+=minf;
c+=minf*dis[t];
}
return c;
}
}mc;

int p(ll x){return x>=60?6400-3*(100-x)*(100-x):0;}

int a[50],b[50],c[50][50];
int main()
{
int n,k,m;
while(scanf("%d%d%d",&n,&k,&m),n||k||m)
{
mc.init();ll cnt=0,sum=0,ans=0;
for(int i=1;i<=m;i++) scanf("%d",a+i),sum+=a[i];
for(int i=1;i<=m;i++) scanf("%d",b+i);
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&c[i][j]);

for(int i=1;i<=n;i++) mc.add(i+m,n+m+1,k,0);
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(c[i][j]) mc.add(j,i+m,k,0);
for(int i=1;i<=m;i++)
{
if(b[i]<60)  cnt+=60-b[i],mc.add(0,i,60-b[i],0xffffffll),b[i]=60;
ans+=a[i]*p(b[i]);
for(int j=b[i];j<100;j++) mc.add(0,i,1,a[i]*(p(j+1)-p(j)));
}
ans+=mc.maxcost(0,n+m+1,n+m+2)-0xffffffll*cnt;
printf("%.6f\n",ans>0?ans/1600.0/sum:0);
}
return 0;
}


H Sum (HDU
4407)

若g(n)为容斥处理出不与(1,n)中不与p互斥的数之和,则对(l,r)区间ans(l,r)=sum(l,r)-(g(r)-g(l)),修改的数字直接保存下来特判一下。

赛后才知道初始一定是1-n的


#include<map>
#include<cstdio>
using namespace std;

typedef long long ll;
const int N=400010;
int p
[10],num
;

int gcd(int a,int b){return b?gcd(b,a%b):a;}
int cal(int x,int p){return gcd(x,p)>1?0:x;}
ll g(int n,int p){ll t=n/p; return t*(t+1)/2*p;}

ll dfs(int idx,int b,int now)
{
ll ans=0;
for(int i=idx;i<num[now];i++) ans+=g(b,p[now][i])-p[now][i]*dfs(i+1,b/p[now][i],now);
return ans;
}

int main()
{
for(int i=2;i<N;i++) if(num[i]==0) for(int j=i;j<N;j+=i) p[j][num[j]++]=i;
int t,n,q;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&q);
map<int,int>c;
while(q--)
{
int op,x,y,p;
scanf("%d%d%d",&op,&x,&y);
if(op==1)
{
scanf("%d",&p);
ll ans=ll(x+y)*(y-x+1)/2-dfs(0,y,p)+dfs(0,x-1,p);
map<int,int>::iterator it,st=c.lower_bound(x),ed=c.upper_bound(y);
for(it=st;it!=ed;it++) ans+=cal(it->second,p)-cal(it->first,p);
printf("%I64d\n",ans);
}
else c[x]=y;
}
}
return 0;
}


I Minimum Spanning Tree (HDU
4408)

最小生成树计数,模板太长,不贴。
YM顾神:http://www.cnblogs.com/Fatedayt/archive/2012/05/10/2494877.html

J Family Name List (HDU
4409)

代码太不精简了,3700B


#include<cstdio>
#include<cstring>
#include<vector>
#include<string>
#include<algorithm>
#include<map>
using namespace std;
const int N=30030;
const int M=N*2;
const int H=20;
string ss
;
struct graph
{
int e,head
;
int ev[M],nxt[M];
void init()
{
e=0;
memset(head,-1,sizeof(head));
}
void addedge(int u,int v)
{
ev[e]=v;
nxt[e]=head[u];
head[u]=e++;
ev[e]=u;
nxt[e]=head[v];
head[v]=e++;
}
}g;

int ln
;
struct LCA
{
int pnt
[H],depth
,stk
;
void init()
{
ln[0]=ln[1]=0;
for(int i=2;i<N;i++) ln[i]=ln[i>>1]+1;
}
int getfather(int x,int len)
{
while(len>0)
{
x=pnt[x][ln[len]];
len-=1<<ln[len];
}return x;
}
int lca(int x,int y)
{
int low=0,high=min(depth[x],depth[y]);
x=getfather(x,depth[x]-high);
y=getfather(y,depth[y]-high);
if(x==y) return x;
while(high-low>1)
{
int mid=ln[high-low-1];
int nx=pnt[x][mid];
int ny=pnt[y][mid];
mid=high-(1<<mid);
if(nx==ny) low=mid;
else {high=mid;x=nx;y=ny;}
}
return pnt[x][ln[high-low]];
}
void build(const graph &g,int root,int n)
{
for(int i=0;i<n;i++)
{
depth[i]=-1;
memset(pnt[i],-1,sizeof(pnt[i]));
}
int top=1;
depth[stk[0]=root]=0;
while(top)
{
int u=stk[--top];
for(int i=g.head[u];~i;i=g.nxt[i])
{
int v=g.ev[i];
if(depth[v]!=-1) continue;
stk[top++]=v;
pnt[v][0]=u;
depth[v]=depth[u]+1;
}
}
for(int i=1;i<H;i++)
{
for(int u=0;u<n;u++) if(pnt[u][i-1]!=-1) pnt[u][i]=pnt[pnt[u][i-1]][i-1];
}
}
}lca;
bool cmp(int a,int b)
{
return ss[a]<ss[b];
}
void dfs(int u,int p)
{
printf("%s\n",ss[u].c_str());
vector<int>son;
for(int i=g.head[u];i!=-1;i=g.nxt[i])
{
if(p==g.ev[i]) continue;
son.push_back(g.ev[i]);
}
sort(son.begin(),son.end(),cmp);
for(int i=0;i<son.size();i++) dfs(son[i],u);
}
char s[100],s2[100],op[2];
int id
,cnt
,fa
;
int main()
{
int n,m;
//freopen("in.txt","r",stdin);
lca.init();
while(scanf("%d",&n),n)
{
g.init();
memset(cnt,0,sizeof(cnt));
map<string,int>ms;
scanf("%s",s);
ss[ms[s]=0]=s;
for(int i=1; i<n; i++)
{
scanf("%s",s);
ss[i]=s;
int k=0;
for(int j=0; s[j]=='.'; j++) k++;
g.addedge(id[k-1],i);
ms[s+k]=id[k]=i;
cnt[id[k-1]]++;
fa[i]=id[k-1];
}
scanf("%d",&m);
lca.build(g,0,n);
for(int i=0;i<m;i++)
{
scanf("%s",op);
if(op[0]=='L') dfs(0,0);
else if(op[0]=='b')
{
scanf("%s",s);
int id=ms[s];
printf("%d\n",cnt[fa[id]]);
}
else
{
scanf("%s%s",s,s2);
int id=lca.lca(ms[s],ms[s2]);
if(id==ms[s]||id==ms[s2]) id=fa[id];
string s=ss[id];
int k=0;
for(int i=0;s[i]=='.';i++) k++;
printf("%s\n",s.c_str()+k);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: