zoukankan      html  css  js  c++  java
  • Codeforces Round #472 Div. 1

      A:某个格子被染黑说明该行和该列同时被选中,使用并查集合并,最后看每个集合中是否有未被染黑的格子即可。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define N 55
    char getc(){char c=getchar();while (c!='.'&&c!='#') c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
    	int x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x*f;
    }
    int n,m,fa[N<<1],u[N],v[N];
    char a[N][N];
    void error(){cout<<"No";exit(0);}
    int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
    signed main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout);
    #endif
    	n=read(),m=read();
    	for (int i=1;i<=n+m;i++) fa[i]=i;
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=m;j++)
    		{
    			a[i][j]=getc();
    			if (a[i][j]=='#') fa[find(j+n)]=find(i);
    		}
    	for (int i=1;i<=n+m;i++)
    	{
    		int p=0,q=0;
    		for (int j=1;j<=n;j++)
    		if (find(j)==i) u[++p]=j;
    		for (int j=1;j<=m;j++)
    		if (find(j+n)==i) v[++q]=j;
    		for (int x=1;x<=p;x++)
    			for (int y=1;y<=q;y++)
    			if (a[u[x]][v[y]]=='.') error();
    	}
    	cout<<"Yes";
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      B:显然Ei和Ej相邻时最优,在固定Ei后Ek越靠后越优,双指针即可。然而我这个弱智硬是写了个分数规划+单调队列。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define N 100010
    char getc(){char c=getchar();while (c!='.'&&c!='#') c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
    	int x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x*f;
    }
    int n,m,a[N],q[N];
    long double calc(int j,long double k){return a[j]-a[j-1]*k;}
    bool check(long double k)
    {
    	int head=1,tail=0;q[++tail]=2;
    	for (int i=3;i<=n;i++)
    	{
    		while (a[q[head]-1]+m<a[i]&&head<=tail) head++;
    		if (head<=tail&&a[i]*(1-k)>=calc(q[head],k)) return 1;
    		while (head<=tail&&calc(i,k)<=calc(q[tail],k)) tail--;
    		q[++tail]=i;
    	}
    	return 0;
    }
    signed main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout);
    #endif
    	n=read(),m=read();
    	for (int i=1;i<=n;i++) a[i]=read();
    	bool flag=0;
    	for (int i=1;i<n-1;i++) if (a[i+2]-a[i]<=m) {flag=1;break;}
    	if (!flag) {cout<<-1;return 0;}
    	long double l=0,r=1,ans;
    	for (int i=1;i<=200;i++)
    	{
    		long double mid=(l+r)/2;
    		if (check(mid)) ans=mid,l=mid;
    		else r=mid;
    	}
    	double u=ans;printf("%.9f",u);
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      C:严格小于=all-严格大于-1,所以即要最小化每天的标记数之和。显然其要大于给定的mi,当然令其为mi+1即最优。但同时每天最多添加一个标记,所以每个数还得对后一个数-1取max。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define N 100010
    char getc(){char c=getchar();while (c!='.'&&c!='#') c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
    	int x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x*f;
    }
    int n,a[N],b[N];
    ll ans;
    signed main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout);
    #endif
    	n=read();
    	for (int i=1;i<=n;i++) a[i]=read(),ans-=a[i]+1;
    	for (int i=1;i<=n;i++) b[i]=max(b[i-1],a[i]+1);
    	for (int i=n;i>=1;i--) b[i]=max(b[i],b[i+1]-1);
    	for (int i=1;i<=n;i++) ans+=b[i];
    	cout<<ans;
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      D:显然到达原点的时间随风速的变化是一个单调函数,且拎出两个函数他们的大小关系也是单调的,于是只需要比较两端点的函数值即可。求出速度两个极限,数二维偏序数量就完了。卡精。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define double long double 
    #define N 100010
    #define lson tree[k].ch[0]
    #define rson tree[k].ch[1]
    char getc(){char c=getchar();while (c!='.'&&c!='#') c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
    	int x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x*f;
    }
    int n,m,cnt,root;
    const double eps=1E-11;
    ll ans;
    struct data
    {
    	double x,y;
    	bool operator <(const data&a) const
    	{
    		return x<a.x||fabs(x-a.x)<eps&&y>a.y;
    	}
    }a[N],b[N],c[N]; 
    struct data2{double x;int ch[2],p,s;
    }tree[N];
    void up(int k){tree[k].s=tree[lson].s+tree[rson].s+1;}
    void move(int &k,int p)
    {
    	int t=tree[k].ch[p];
    	tree[k].ch[p]=tree[t].ch[!p],tree[t].ch[!p]=k,up(k),up(t),k=t;
    }
    void ins(int &k,double x)
    {
    	if (k==0){k=++cnt;tree[k].x=x;lson=rson=0;tree[k].p=rand();tree[k].s=1;return;}
    	tree[k].s++;
    	if (tree[k].x>x) {ins(lson,x);if (tree[lson].p>tree[k].p) move(k,0);}
    	else {ins(rson,x);if (tree[rson].p>tree[k].p) move(k,1);}
    }
    int query(int k,double x)
    {
    	if (k==0) return 0;
    	if (tree[k].x+eps<x) return query(rson,x);
    	else return query(lson,x)+tree[rson].s+1;
    }
    void clear(){root=cnt=0;}
    void solve(int l,int r)
    {
    	int t=0;
    	for (int i=l;i<=r;i++) t++,c[t].x=-a[i].x/(a[i].y+m),c[t].y=-a[i].x/(a[i].y-m);
    	sort(c+1,c+t+1);clear();
    	for (int i=1;i<=t;i++)
    	{
    		ans+=query(root,c[i].y);
    		ins(root,c[i].y);
    	}
    }
    signed main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout);
    #endif
    	srand(20020509);
    	n=read(),m=read();
    	for (int i=1;i<=n;i++) a[i].x=-read(),a[i].y=read();
    	for (int i=1;i<=n;i++)
    	{
    		double x=a[i].x/(a[i].y+m),y=a[i].x/(a[i].y-m);
    		a[i]=(data){x,y};
    	}
    	sort(a+1,a+n+1);
    	for (int i=1;i<=n;i++)
    	{
    		ans+=query(root,a[i].y);
    		ins(root,a[i].y);
    	}
    	cout<<ans;
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      E:确定了哪些重要盒子放在顶部且不计入答案后,剩余的重要盒子看起来应该从大到小放置,但有一些比较麻烦的边界情况比如样例2。不妨将堆出来的塔翻转过来,这样就变成了要求顶部在范围内,问题就变得清新起来。于是先背包出不重要盒子的所有高度,然后将重要盒子从大到小排序,设f[i][j]为前i个重要盒子高度为j时的最优答案,转移显然,初值即仅对存在的不重要盒子集合高度设为0,其他设为-inf。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<bitset>
    using namespace std;
    #define ll long long
    #define N 10010
    char getc(){char c=getchar();while (c!='.'&&c!='#') c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
    	int x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x*f;
    }
    int n,m,l,r,u,v,a[N],b[N],c[N],f[N],ans;
    bitset<N> F;
    signed main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout);
    #endif
    	n=read(),l=read(),r=read();
    	for (int i=1;i<=n;i++) m+=c[i]=read();
    	l=m-l,r=m-r;swap(l,r);
    	for (int i=1;i<=n;i++) if (read()) a[++u]=c[i];else b[++v]=c[i];
    	F[0]=1;
    	for (int i=1;i<=v;i++)
    	F|=F<<b[i];
    	sort(a+1,a+u+1);reverse(a+1,a+u+1);
    	memset(f,200,sizeof(f));for (int i=0;i<=10000;i++) if (F[i]) f[i]=0;
    	for (int i=1;i<=u;i++)
    		for (int j=10000;j>=a[i];j--)
    		f[j]=max(f[j],f[j-a[i]]+(j>=l&&j<=r));
    	for (int i=0;i<=10000;i++) ans=max(ans,f[i]);
    	cout<<ans;
    	return 0;
    }	
    

      

  • 相关阅读:
    python相关的报错处理
    各版本数据库初次登录时,强制修改密码
    机器被感染病毒文件zigw的处理流程
    Let's encrypt申请泛域名证书以及报错处理
    添加/修改保存
    request.getRemoteUser() Spring Security做权限控制后
    hibernate hbm.xml配置映射
    hibernate 注解配置<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/X
    Web.xml配置详解之context-param
    在web.xml中通过contextConfigLocation配置spring
  • 原文地址:https://www.cnblogs.com/Gloid/p/10425943.html
Copyright © 2011-2022 走看看