zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 100 (Rated for Div. 2) 补题情况

    战况(被hack掉一个 -2)

    A. Dungeon

    数学题,实际上一次抹掉三个同时,并且还能再抹掉6个所以一波就能干掉9个,至于他怎么干的完全可以不用去考虑,这里贪心即可。但是要注意看他干了几波,如果干的波数小于(min(a,b,c))的话,那么肯定也是不行的。

    所以首先判断((a+b+c)mod9 == 0?) 如果可以再判断是否(frac{a+b+c}{9}leq min(a,b,c)) 即可

    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
    	int t;
    	scanf("%d",&t);
    	while(t--)
    	{
    		long long a,b,c,d=INT_MAX;
    		scanf("%lld%lld%lld",&a,&b,&c);
    		long long s=a+b+c;
    		if(s%9==0)
    		{
    			s/=9;
    			if(s<=min(min(a,b),c)) puts("YES");
    			else puts("NO");
    		}
    		else puts("NO");
    	}
    } 
    

    B. Find The Array

    构造题,两种做法。

    第一种是直接构造所有的(a[i])的同一位数的二进制数即可。这样能保证所有的整除关系。

    例如(a[i]=5)那么(5=(101)_2) 我们构造(b[i]=4=(100)_2)这样我们的差值(|a[i]-b[i]|=1=(001)_2)可以证明这个插值一定是小于等于(lfloorfrac{a[i]}{2} floor)的。因为我之前的第一位已经占了一个一,我数向下取整除以二就是右移一位,并且我之前前面一定占有至少相同的一,所以相差不会大于要求。

    #include <bits/stdc++.h>
    using namespace std;
    int a[1005];
    int main()
    {
    	int t;
    	cin>>t;
    	while(t--)
    	{
    		int n;
    		cin>>n;
    		for(int i=1;i<=n;i++) cin>>a[i];
    		int now=1;
    		for(int i=1;i<=n;i++)
    		{
    			int now=1;
    			while(1)
    			{
    				if(now*2>a[i]) 
    				{
    					cout<<now<<" ";
    					break;
    				}
    				now*=2;
    			}
    		}
    		cout<<"
    ";
    	}
    }
    

    第二种做法是,我们可以认为(S=sum_{i=1}^{n}a[i]=S_{odd}+S_{even})也就是说我们总和等于原数列的奇数项加上偶数项,我们看哪一项大就把(b[i])对应的等于(a[i])其他都设置成为1,这样的话(2sum_{i=1}^{n}|a[i]-b[i]|=2(a[1]+a[3]+...+a[n-1]-frac{n}{2})=2S_{odd}-n)(假设n是一个偶数,并且偶数项大于等于奇数项)​。因为(S_{odd}leq S_{even})所以(2S_{odd}leq S),所以(2S_{odd}-nleq S),所以这么分的话(2sum_{i=1}^{n}|a[i]-b[i]|leq S)满足题目要求。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll a[105],s1,s2;
    int main()
    {
    	int t;
    	scanf("%d",&t);
    	while(t--)
    	{
    		int n;
    		s1=s2=0;
    		scanf("%d",&n);
    		for(int i=1;i<=n;i++) 
    		{
    			scanf("%lld",&a[i]);
    			if(i&1) s1+=a[i];
    			else s2+=a[i];
    		}
    		if(s1<=s2)
    		{
    			for(int i=1;i<=n;i++) if(i&1) printf("1 ");else printf("%lld ",a[i]);
    		}
    		else
    		{
    			for(int i=1;i<=n;i++) if(i&1) printf("%lld ",a[i]);else printf("1 ");
    		}
    		puts("");
    	}
    }
    

    C. Busy Robot

    直接模拟的题,按照题意模拟即可

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll t[100005],x[100005];
    set<ll> st;
    int main()
    {
    	int T;
    	scanf("%d",&T);
    	while(T--)
    	{
    		int n;
    		scanf("%d",&n);
    		for(int i=1;i<=n;i++) scanf("%lld%lld",&t[i],&x[i]); 
    		t[n+1]=INT_MAX;
    		t[n+1]+=t[n+1];
    		ll tm=0,ans=0,pos=0,l=0,r=0,ltm=0,f=1,lpos=0;
    		for(int i=1;i<=n;i++)
    		{
    			if(t[i]>=tm)  
    			{
    				ll d1=0;
    				ll d2=d1+t[i+1]-t[i];
    				if(x[i]>=pos)
    				{
    					f=1;
    					l=pos+d1;
    					r=pos+d2;
    				}
    				else
    				{
    					f=-1;
    					r=pos-d1;
    					l=pos-d2;
    				}
    				if(x[i]>=l&&x[i]<=r) ans++;
    				ltm=t[i];
    				tm=t[i]+llabs(pos-x[i]);
    				lpos=pos;
    				pos=x[i];
    			}
    			else
    			{
    				ll d1=t[i]-ltm;
    				ll d2=min(tm,t[i+1])-ltm;
    				if(f==1)
    				{
    					l=lpos+d1;
    					r=lpos+d2;	
    				}
    				else
    				{
    					r=lpos-d1;
    					l=lpos-d2;	
    				}	
    				if(x[i]>=l&&x[i]<=r) ans++;
    			}	
    		}
    		printf("%lld
    ",ans);
    	}
    } 
    

    D. Pairs

    给你(2n)个整数(1,2,3,4,...,2n)让你从中分出(n)个数对并且从中任意选出(x)个数对的最小值为(b[i]),从(n-x)个数对中选出最大值为(b[i]),且满足对于选出来的(b[i])要等于(a[i])并且(a[i])为输入的数组,求(0leq xleq n)中有多少个(x)能够满足要求。

    首先找出(2n)中剩下的数不在(a[i])中的让他们组成(c[i]),然后把(c[i])排序,顺便把(a[i])也排序,因为我们任意选出数对来构造(b[i])所以原来数组(a[i])的顺序也无关紧要。如果我们要选择一个数对让他们的小的数成为(b[i])那么我对应的这个位置上的(a[i])必须得从(c)数组中有比我大的数才可以否则根本无法实现,反之亦然(vice versa)。于是我们就可以贪心的看看每个数到底有几个比他大的数在(c)数组中,有几个比他小的数。

    这里还需要发现一个事,就是我如果给定的资源也就是数的个数是合适的话,我一定能够分配好,不管怎么分配。那么我只要确定好上下界限,也就是(x)的上下界限(l,r)即可,答案就是(r-l+1)因为我可以用的资源是够的,所以一定能够分配好。

    但是我们怎么求的(l,r)呢?

    实际上(r)就是最多的能有在(c)中比(a[i])大的数的个数,这样就可以用小的数构造(b[i])

    (l)就是(n-最多的能有在c中比a[i]小的数的个数)因为这些数没有比他们小的,只能用大的数构造(b[i])

    所以现在问题就是找上面的什么比(a[i])大比(a[i])小的什么的个数了。

    我们需要考虑一下这个数据

    2

    2 3

    可以发现1不在(a[i])中并且比2和3都要小,但是我这个1只能分配个一个,所以我需要从左到右的去寻找,来判断一下是否能够分配。

    同样的4都比2 3大所以要从右到左的去寻找,来判断一下是否能够分配。

    最终答案就是(r-l+1)时间复杂度为(O(NlogN))

    #include <bits/stdc++.h>
    using namespace std;
    int mk[500005],a[500005],b[500005],maxn[500005],minn[500005],n;
    int main()
    {
    	int t;
    	scanf("%d",&t);
    	while(t--)
    	{
    		int p=0,m1,m2,x=0,y=0,ans=0;
    		scanf("%d",&n);
    		for(int i=1;i<=2*n;i++) mk[i]=0;
    		for(int i=1;i<=n;i++) scanf("%d",&a[i]),mk[a[i]]++;
    		for(int i=1;i<=2*n;i++) if(!mk[i]) b[++p]=i;
    		sort(b+1,b+1+p);
    		sort(a+1,a+1+n);
    		for(int i=1;i<=n;i++)
    		{
    			m2=lower_bound(b+1,b+1+p,a[i])-b-1;
    			if(m2>y) y++;
    		}
    		for(int i=n;i;i--)
    		{
    			m1=n-(upper_bound(b+1,b+1+p,a[i])-b)+1;
    			if(m1>x) x++;
    		}
    		int l=n-y,r=x,L=l;
    		printf("%d
    ",r-l+1);
    	}
    }
    

    小结

    B不被hack就好了。。。A想的有点慢。

  • 相关阅读:
    jQuery使用手册之Ajax支持(8)
    jQuery使用手册之动态效果(6)
    jquery插件 操作select
    提高jQuery的性能
    jQuery起点教程之使用AJAX(4)
    jQuery起点教程之插件制作(7)
    IE开发工具栏
    信息安全之DNS欺骗详解
    颜色取色器
    使DIV不被select等控件遮挡的解决办法
  • 原文地址:https://www.cnblogs.com/baccano-acmer/p/14158450.html
Copyright © 2011-2022 走看看