• Codeforces Round #514 (Div. 2)



    Codeforces 1059

    比赛链接

    好失败啊。。
    D挺简单的,但是没做。E读错题了,以为链可以拐弯,不知这样怎么求每个点最远延伸距离(想了想好像不难不过也好像很麻烦就弃疗了)。不然不就是个显然的贪心么。。

    Update:E读错题了,读成NOIP Day1T3了。

    A.Cashier

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define gc() getchar()
    typedef long long LL;
    const int N=1e5+7;
    
    int n,L,a,t[N],l[N];
    
    inline int read()
    {
    	int now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    
    int main()
    {
    	n=read(), L=read(), a=read();
    	for(int i=1; i<=n; ++i) t[i]=read(),l[i]=read();
    	int ans=0, las=0; t[++n]=L;
    	for(int i=1; i<=n; ++i)
    	{
    		ans+=(t[i]-las)/a;
    		las=t[i]+l[i];
    	}
    	printf("%d
    ",ans);
    
    	return 0;
    }
    

    B.Forgery

    #include <cstdio>
    #include <cctype>
    #define gc() getchar()
    using namespace std;
    const int N=1005,B=65;
    const int dx[9]={-1,-1,-1,0,1,1,1,0};
    const int dy[9]={-1,0,1,1,1,0,-1,-1};
    
    int vis[N][N];
    char s[N][N];
    
    inline int read()
    {
    	int now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    
    int main()
    {
    	int n=read(),m=read();
    	for(int i=1; i<=n; ++i) scanf("%s", s[i] + 1);
    	for(int i=2; i<n; ++i)
    	{
    		for(int j=2; j<m; j++)
    		{
    			bool flag=0;
    			for(int k=0; k<8; k++)
    			{
    				int xn=i+dx[k], yn=j+dy[k];
    				if(s[xn][yn] != '#')
    				{
    					flag=1;
    					break;
    				}
    			}
    			if(flag) continue;
    			for(int k=0; k<8; k++)
    			{
    				int xn=i+dx[k], yn=j+dy[k];
    				vis[xn][yn]=1;
    			}
    		}
    	}
    	for(int i=1; i<=n; ++i)
    	{
    		for(int j=1; j<=m; j++)
    		{
    			if(s[i][j]=='#' && vis[i][j]!=1)
    			{
    				puts("NO");
    				return 0;
    			}
    		}
    	}
    	puts("YES");
    	return 0;
    }
    

    C.Sequence Transformation

    //not mine...
    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define gc() getchar()
    
    int Ans[1000005];
    
    inline int read()
    {
    	int now=0,f=1;register char c=gc();
    	for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now*f;
    }
    
    int main()
    {
    	int n=read();
    	if(n==1) printf("1
    ");
    	if(n==2) printf("1 2
    ");
    	if(n==3) printf("1 1 3
    ");
    	if(n<=3) return 0;
    
    	int d=1, p1=2, p2=3, cnt=0;
    
    	while(d!=n)
    	{
    		int tot=n/d;
    		if(tot-n/p1 < tot-n/p2)
    		{
    			for(int i=d; i<=n; i+=d)
    				if(i%p1) Ans[++cnt]=d;
    			d=p1;
    		}
    		else
    		{
    			for(int i=d; i<=n; i+=d)
    				if(i%p2) Ans[++cnt]=d;
    			d=p2;
    		}
    		p1=d<<1;
    		p2=3*d;
    		if(d==n) Ans[++cnt]=d;
    		if(cnt==n) break;
    	}
    	for(int i=1; i<=n; ++i) printf("%d ", Ans[i]);
    
    	return 0;
    }
    

    比赛结束后

    D.Nature Reserve(二分)

    二分半径r。我们发现半径确定后,圆心的纵坐标也确定(在y=r上)。
    这样我们要求是否存在圆心在y=r上的覆盖所有点的圆。对每个点画一个半径为r的圆,它们需要在y=r这条直线上有交。
    每个圆到y=r的两个交点可以用勾股定理算出来,可以转成区间是否有交的问题。求最左的右端点和最右的左端点就行了。
    因为要与x轴相切,所以半径可能非常大,用勾股定理可以得到最大是5e13+。因为范围较大注意简化运算减少误差。

    //61ms	7700KB
    #include <cmath>
    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define gc() getchar()
    #define MAXIN 200000
    //#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
    typedef long long LL;
    const int N=1e6+6;
    
    int n,x[N],y[N];
    char IN[MAXIN],*SS=IN,*TT=IN;
    
    inline int read()
    {
    	int now=0,f=1;register char c=gc();
    	for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now*f;
    }
    bool Check(double r)
    {
    	double L=-1e18,R=1e18,tmp;
    	for(int i=1; i<=n; ++i)
    	{
    		if(r+r<y[i]) return 0;
    		tmp=sqrt(1.0*(r+r-y[i])*y[i]);
    		L=std::max(L,-tmp+x[i]), R=std::min(R,tmp+x[i]);
    		if(L>R) return 0;
    	}
    	return 1;
    }
    
    int main()
    {
    	n=read(); int cnt=0;
    	for(int i=1; i<=n; ++i) x[i]=read(),y[i]=read(),cnt+=(y[i]<0);
    	if(cnt)
    	{
    		if(cnt!=n) return puts("-1"),0;
    		for(int i=1; i<=n; ++i) y[i]=-y[i];
    	}
    	double l=0,r=1e14,mid;
    	for(int T=80; T--; )
    	{
    //		if(l>1 && l+1>r) mid=sqrt(l*r);//几何平均数该这么写么。。
    //		else mid=(l+r)*0.5;
    		if(Check(mid=(l+r)*0.5)) r=mid;
    		else l=mid;
    	}
    	printf("%.7lf
    ",l);
    
    	return 0;
    }
    

    E.Split the Tree(贪心 并查集/二分)

    每条链只能向上覆盖,那贪心策略就显然了啊(子树每个点求最远能向上覆盖的距离)。
    可以在DFS的过程中存下该链的信息,然后二分。也可以直接用并查集合并被覆盖的链。

    //31ms	6200KB
    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define gc() getchar()
    #define MAXIN 200000
    //#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
    typedef long long LL;
    const int N=1e5+6;
    
    int w[N],fa[N],F[N],q[N],dgr[N],dep[N];
    LL sum[N];
    bool vis[N];
    char IN[MAXIN],*SS=IN,*TT=IN;
    
    inline int read()
    {
    	int now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    inline LL readll()
    {
    	LL now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    int Find(int x)
    {
    	return x==F[x]?x:F[x]=Find(F[x]);
    }
    
    int main()
    {
    	int n=read(),L=read(); LL S=readll();
    	for(int i=1; i<=n; ++i) if((w[i]=read())>S) return puts("-1"),0;
    	for(int i=2; i<=n; ++i) ++dgr[fa[i]=read()];
    	for(int i=1; i<=n; ++i) F[i]=i,sum[i]=sum[fa[i]]+w[i],dep[i]=dep[fa[i]]+1;
    
    	int h=0,t=0,Ans=0;
    	for(int i=1; i<=n; ++i) if(!dgr[i]) q[t++]=i;
    	while(h<t)
    	{
    		int x=q[h++];
    		if(vis[x]) continue;
    		++Ans;
    
    		int num=0; LL s=0;
    		while(x)
    		{
    			int nxt=Find(x);
    			num+=dep[x]-dep[nxt]+1, s+=sum[x]-sum[nxt]+w[nxt];
    			if(num>L||s>S) break;
    
    			vis[nxt]=1;
    			if(!--dgr[fa[nxt]]) q[t++]=fa[nxt];
    			F[nxt]=Find(fa[F[nxt]]), x=fa[nxt];
    		}
    	}
    	printf("%d
    ",Ans);
    
    	return 0;
    }
    
  • 相关阅读:
    一起谈.NET技术,深入ASP.NET 2.0的提供者模型(2) 狼人:
    一起谈.NET技术,从.NET中委托写法的演变谈开去(上):委托与匿名方法 狼人:
    一起谈.NET技术,将Flash 嵌入WPF 程序 狼人:
    一起谈.NET技术,数组排序方法的性能比较(中):Array.Sort<T> 实现分析 狼人:
    人一生当中最应该珍惜的十种人
    《程序员的第一年》复习一下C#的【封装 多态 继承 简单计算器源码实例】
    myeclipse 修改模板
    三星将在百思买零售店内开设1400家体验店
    谷歌Q3推Android本 蚕食自己平板市场
    Spring Setting
  • 原文地址:https://www.cnblogs.com/SovietPower/p/9752393.html
Copyright © 2020-2023  润新知