超链接为pdf题面,请先登录。
渣题
用S来表示长城的长度,t来表示目前的所用的时间。
不断地读入a,b,t,而t不断地加 (b-a+1)t,表示这一段所用的时间。最后S不断减掉 bi-ai+1,则就是剩下的长度了。最后t还要加上加上s1,计算普通的长城的时间。
BAS code:
#include
int s,n,x,y,z,t,i;
int main()
{
freopen("china.in","r",stdin);
freopen("china.out","w",stdout);
scanf("%d%d",&s,&n);
for(i=1;i<=n;i++)
{
scanf("%d%d%d",&x,&y,&z);
t+=(y-x+1)*z;
s-=(y-x+1);
}
printf("%d\n",t+s);
}
对于此题,暴力枚举:
用f[I,j]表示第i座建筑高度为j时的最大面积。则i-1
ZOJ code:
#include
#define max(a,b) ((a)>(b)?(a):(b))
using namespace std;
int a[1000010];
int main()
{
freopen("england.in","r",stdin);
freopen("england.out","w",stdout);
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
int mx=-1;
for(int i=1;i<=n;i++)
mx=max(a[i],mx);
int s=0;
int ans=-1;
for(int i=1;i<=mx;i++)
{
for(int j=1;j<=n;j++)
{
if(a[j]>=i)
{
s+=i;
continue;
}
if(a[j]<i)
{
ans=max(ans,s);
s=0;
continue;
}
}
ans=max(ans,s);
s=0;
}
printf("%d",ans);
fclose(stdin);
fclose(stdout);
return 0;
}
这道理,正解为搜索,可以用最短路做。
首先,先教大家两个判断公式:
如果Q,P1,P2满足:(Qx-P1x)(P2y-P2y)=(P2x-P1x)(Qy-P1y)
则Q,P1,P2在同一条直线上
如果满足(1),且min(P1x,P2x) <= Qx,Qx<=max(P1x,P2x)
且min(P1y,P2y)<=Qy,Qy<=max(P1y,P2y))
则Q在P1,P2所形成的线段之间
然后理解理解:
一开始,球权在泽择手中,他可以选择自己射门,也可以选择传给其他球员射门,选择时间略短的一种方案(先保证没有流氓拦截)
而被传球的球员也可以选择自己射门,也可以选择传给其他球员射门
则:
⑴举每个泽泽队伍的队员B,看看是A直接射门优还是A传球给B射门优
⑵举每个泽泽队伍的队员C,看看是B直接射门优还是B传球给C射门优
DFS code:
#include
#include
#include
#define r register int
using namespace std;
int n,m,x[301],y[301],a,b,bz[5001][5001],l[301];
double map[302][302],ans;
void dfs(int k,double t)
{
if (!ans||ans>t+map[301][k])
ans=t+map[301][k];
for (r i=1;i<=n;++i)
if (i-k)
if (map[i][k]+1)
if (!l[i]||l[i]>t+map[i][k])
{
l[i]=t+map[i][k];
dfs(i,t+map[i][k]);
}
}
int main()
{
freopen("brazil.in","r",stdin);
freopen("brazil.out","w",stdout);
scanf("%d%d%d%d",&a,&b,&n,&m);
for (r i=1;i<=n;++i)
scanf("%d%d",&x[i],&y[i]);
for (r i=1;i<=m;++i)
{
int x2,y2;
scanf("%d%d",&x2,&y2);
bz[x2+2500][y2+2500]=1;
}
for (r i=1;i<=n;++i)
for (r j=i+1;j<=n;++j)
{
bool bz2=1;
int p=x[i]-x[j],q=y[i]-y[j];
int o=__gcd(p,q),nowx=x[j],nowy=y[j];
if (o<0)
o=-o;
p/=o,q/=o;
for (r k=1;k<o;++k)
{
nowx+=p;nowy+=q;
if (bz[nowx+2500][nowy+2500])
{
bz2=0;
break;
}
}
if (bz2)
map[i][j]=map[j][i]=sqrt(double((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])));
else
map[i][j]=map[j][i]=-1;
}
for (r i=1;i<=n;++i)
map[i][301]=map[301][i]=sqrt(double((x[i]-a)*(x[i]-a)+(y[i]-b)*(y[i]-b)))*2;
ans=map[1][301];
dfs(1,0);
printf("%d",int(ans+0.5));
fclose(stdin);
fclose(stdout);
return 0;
}
而最短路代码,首先构造路线,然后进行搜索最优:
SPFA code:
#include
#include
#include
#define INF 2147483647.0
#define ER 0.00000001
using namespace std;
queue<int> q;
struct P
{
int x,y;
}a[3100],b[1100],d;
struct Edge
{
int to,next;double val;
}edge[450100];
inline int max(int a,int b){return a>b?a:b;}
inline int min(int a,int b){return a<b?a:b;}
int n,m,ans,len,head[3100];
bool inq[3100];
double dis[3100];
inline double gd(int x1,int y1,int x2,int y2)
{
return sqrt((double)((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));
}
inline bool eq(double a,double b)
{
return fabs(a-b)<=ER;
}
inline bool br(double a,double b)
{
return (a-b)>ER;
}
bool line(P a,P b,P c)
{
if(fabs(gd(a.x,a.y,b.x,b.y)-gd(a.x,a.y,c.x,c.y)-gd(c.x,c.y,b.x,b.y))<0.00001)
return false;
return true;
}
void add_edge(int u,int v,double f)
{
edge[++len]=(Edge){v,head[u],f};
head[u]=len;
}
void spfa()
{
for(int i=2;i<=n;++i)
dis[i]=INF;
inq[1]=1;q.push(1);
int u,v;
while(!q.empty())
{
u=q.front();
q.pop();
inq[u]=0;
for(int i=head[u];i;i=edge[i].next)
{
v=edge[i].to;
if(dis[v]>dis[u]+edge[i].val)
dis[v]=edge[i].val+dis[u];
if(!inq[v])
{
q.push(v);
inq[v]=1;
}
}
}
}
int main()
{
freopen("brazil.in","r",stdin);
freopen("brazil.out","w",stdout);
scanf("%d %d %d %d",&d.x,&d.y,&n,&m);
for(int i=1;i<=n;++i)
scanf("%d %d",&a[i].x,&a[i].y);
for(int i=1;i<=m;++i)
scanf("%d %d",&b[i].x,&b[i].y);
for(int i=1;i<=n;++i)
for(int j=i+1;j<=n;++j)
{
bool bz=0;
for(int k=1;k<=m;++k)
if(!line(a[i],a[j],b[k]))
{
bz=1;break;
}
if(!bz)
{
add_edge(i,j,gd(a[i].x,a[i].y,a[j].x,a[j].y));
add_edge(j,i,gd(a[i].x,a[i].y,a[j].x,a[j].y));
}
}
for(int i=1;i<=n;++i)
add_edge(i,n+1,gd(a[i].x,a[i].y,d.x,d.y)*2);
++n;
spfa();
if((int)dis[n]*1.0+0.5>=dis[n])
ans=(int)dis[n];
else
ans=(int)dis[n]+1;
printf("%d",(int)ans);
return 0;
}