CF 637 div2

有空补上。

A题:

题意:t个测试数据,每个数据给出n个数,每个数在[a-b,a+b],询问n个数的和是否在[c-d,c+d]上。

分析:直接判断n个数的最大值是否小于c-d或者最小值大于c+d,满足的话输出No。否则输出Yes。

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 int t,n,a,b,c,d;
 5 int main(void)
 6 {
 7     scanf("%d",&t);
 8     while(t--)
 9     {
10         scanf("%d %d %d %d %d",&n,&a,&b,&c,&d);
11         if(n*(a-b)>c+d||n*(a+b)<c-d)printf("No
");
12         else printf("Yes
");
13     }
14     return 0;
15 }

B题:

题意:对每一个例给出一组数据,求该组数据中一个长度为k的区间的最大山峰数以及该区间的左下标。

分析:对每一个山峰?(英语不好)做一个标记,然后设置一个长度为k的区间,从1到k,然后将这个区间滑动到最后,过程中更新最大山峰数以及区    间左下标。怎么更新呢?设置一个变量now记录当前的山峰数,向右滑动时如果加入的点是标记点的后一个,那么now++;出去的点如果是标记点的前一个,  now--。最后输出即可。

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 int t,n,k,a[210000],f[210000];
 5 int main(void)
 6 {
 7     scanf("%d",&t);
 8     while(t--)
 9     {
10         scanf("%d %d",&n,&k);
11         for(int i=1;i<=n;i++)
12         {
13             scanf("%d",&a[i]);
14             f[i]=0;
15         }
16         for(int i=2;i<n;i++)
17         {
18             if(a[i]>a[i+1]&&a[i]>a[i-1])f[i]=1;
19         }
20         int maxx=0,now=0,left=1;
21         for(int i=2;i<k;i++)
22         {
23             if(f[i])now++;
24         }
25         maxx=maxx>now?maxx:now;
26         for(int i=k+1;i<=n;i++)
27         {
28             if(f[i-1])now++;
29             if(f[i-k+1])now--;
30             if(now>maxx)
31             {
32                 maxx=now;
33                 left=i-k+1;
34             }
35         }
36         printf("%d %d
",maxx+1,left);
37     }
38     return 0;
39 }

C题:

题意:(理解了好久)对每组排列,判断生成器能否生成该组排列,生成器生成排列规则如下:

1.对于每一个下标j,1<=j<=n,rj等于后面最近的空位下标,否则为0。

2.对于每一个下标t,cntt等于rj=t的数量(1<=j<=n),如果该位置被占用则无效。

3.生成器必须取cntt最大的位置存放当前的数,如果不止一个最大,那可以在这些位置中任意选择。

分析:首先存放的数对cnt和r没有影响,关键是存放的位置,容易知道一开始没有放任何数时,所有的cntt都等于1,假设我们第一个是存放的位置是i,那么就有两种情况:

(1)i=n,也就是放在最后一位,此时cnt n无效,而其他的所有cntt仍为1,因为对1<=j<=n,rj=j;所有对1<=t<=n-1,cntt=1。我们接下来相当于来到把n-1个数放进n-1个位置,相比原来仅仅少了一个数。

(2)i<n,此时ri=i+1,ri+1=i+1,cnti无效,而cnti+1=2,其他所有cntt=1,因此下一个数只能存放在i+1位置,而这又导致cnti+2最大,从而得到结论:如果这个位置紧邻着下一个空位,那么下一个数必定存在下一个空位。

最后思路便是:对于1<=i<n,a[i+1]==a[i]+1 or a[i+1]<a[i],否则不能生成该排列。

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 int t,n,p[110000];
 5 int main(void)
 6 {
 7     cin>>t;
 8     while(t--)
 9     {
10         cin>>n;
11         for(int i=1;i<=n;i++)cin>>p[i];
12         int i;
13         for(i=2;i<=n;i++)
14         {
15             if(p[i]>p[i-1]+1)break;
16         }
17         if(i<=n)printf("No
");
18         else printf("Yes
");
19     }
20     return 0;
21 }
原文地址:https://www.cnblogs.com/yanying7/p/12767229.html