• Codeforces Round #637 (Div. 2)


    A 已知有n个数,他们的范围是[a-b,a+b],问这n个数(可以相等)的和是否能在[c-d,c+d]的范围内,直接判断即可。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=200010;
    int t,n,m;
    int main()
    {
    	cin>>t;
    	while(t--)
    	{
    		int a,b,c,d;
    		cin>>n>>a>>b>>c>>d;
    		if((a+b)*n<(c-d)||(a-b)*n>(c+d)) puts("No");
    		else puts("Yes");
    	}
    	return 0;
    }
    

    B 已知一个数组,如果a[i]>a[i-1]并且ai>a[i+1]那么ai就是一个山峰,如果在区间l[l,l+k-1]内有m个山峰,那么你的某种物品就被分成m+1份了,输出最大的m+1和区间起点l,如果有多个输出最小的l。预处理一下前面有多少个山峰,sum[i]就是前i个数的山峰数量(包括第i个数),这样区间内的山峰数量就可以计算了。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    const int N=200010;
    int t,n,m;
    int a[N],sum[N];
    int main()
    {
    	cin>>t;
    	while(t--)
    	{
    		cin>>n>>m;
    		for(int i=1;i<=n;i++) cin>>a[i];
    		int k=0,l=1;
    		for(int i=2;i<=n;i++)
    		{
    			if(a[i]>a[i-1]&&a[i]>a[i+1]&&i<n) sum[i]=sum[i-2]+1;
    			else sum[i]=sum[i-1];
    			if(i>=m&&sum[i-1]-sum[i-m+1]+1>k)
    			{
    				l=i-m+1;
    				k=sum[i-1]-sum[i-m+1]+1;
    			}
    		}
    		cout<<k<<' '<<l<<endl;
    	}
    	return 0;
    }
    

    C 题意比较绕,读懂了就好理解了,按照题面意思生成随机数组,生成规则是:
    第i步为数字i选择一个位置,选择依据是对于任意数字j(1<=j<=n)从第j个位置向后寻找第一个没有被占据的位置记为r[j],没有找到的不用管,最后统计所有数t(1<=t<=n)在r[]内出现的次数记为count[t],选择count[t]最大的数字t就是数字i的位置(如果有多个任意一个都可以)。

    思路:假设n=7,i=1的时候count数组全为0,随意第一个,位置都可以任意选;假设选择5,接下来给2选位置,r数组: 1 2 3 4 6 6 7(第5个位置后第一个没被选的位置是6)count数组:1 1 1 1 0 2 1这时候只能选位置6;
    然后选3的位置 r数组:1 2 3 4 7 7 7 ,count数组就是1 1 1 1 0 0 3,这时候就只能选位置7,
    再给4选位置,r数组1 2 3 4 * * * (*)表示没找到rj,count数组:1 1 1 1 0 0 0 ,
    这时候位置1到4都可以选,看第一步是不是很类似,令n=4就一模一样了;

    对于n个数来说,1的位置可以任意选,假设选择t[1],选2的位置的时候 r数组除了t[1]的所有位置i都是i(r[i]=i,i!=t[1]),只有t[1]例外r[t[1]=t[1]+1,所以count数组中只有count[t[1]+1]=2,其他都是1或者0(count[t[1]]=0),所以2只能选择位置t[1]+1,3的位置也一样只能选择t[1]+2,所以t[1]往后都是递增的且差值等1,直到位置n被选择后,当前数可以选择t[1]之前的数,这时令n=t[1]-1,就是回到第一步的时候了。

    所以对于随机数组ans,ans[i-1]<n的时候ans[i]必须等于ans[i-1]+1,当ans[i-1]==n时, 就可以选择前面的任意数了,相当于将全面的区间划分成连个,然后再后一个区间内一次递增,直到完全选择,然后再再前一个区间内划分继续一样的操作直到1到n的数全部出现。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    const int N=200010;
    int t,n,m;
    int a[N],sum[N];
    int main()
    {
    	cin>>t;
    	while(t--)
    	{
    		cin>>n;
    		for(int i=1;i<=n;i++) cin>>a[i];
    		int l=1,r=n,k=-1;初始区间是[1,n],k=-1表示要选择dl来划分区间了
    		bool flag=1;
    		for(int i=1;i<=n;i++)//当时想的复杂了一些,代码就繁琐了
    		{
    			if(k==-1)//该划分区间了
    			{
    				if(a[i]<l||a[i]>r)
    				{
    				 	flag=0;
    				 	break;
    				}
    				else 
    				{
    					l=a[i];//这个时候就是dl
    					if(l==r)//直接选择了区间最后一个点
    					{
    						l=1;
    						r--;
    					}
    					else
    						k=a[i]-1;//k保存dl-1
    				}
    			}
    			else 
    			{
    				if(a[i]!=l+1) //划分过区间后就只能依次递增了
    				{
    					flag=0;
    					break;
    				}
    				else 
    				{
    					l=a[i];
    					if(l==r) //[dl,r]内的被选完了就缩小区间呗
    					{
    						r=k;//k=dl-1
    						l=1;//区间左端点会一直是1直到结束了
    						k=-1;//该划分区间了
    					}
    				}
    			}
    		}
    		if(flag) puts("Yes");
    		else puts("No");
    	}
    	return 0;
    }
    

    D待补,溜了溜了

  • 相关阅读:
    递归的一些应用(一)遍历文件夹
    获取指定路径下文件夹所有文件的大小
    JavaScript Color Picker
    在ASP.NET中,用javascript给CuteEditor控件赋值
    通过URL判断文件是否有存在
    语音验证码
    [链接].net 学习网站
    [音乐]梦中的婚礼
    [转载]天堂猎人影院的爱情狩猎
    为应用程序添加消息过滤器
  • 原文地址:https://www.cnblogs.com/neflibata/p/12871747.html
Copyright © 2020-2023  润新知