CF round#640 第一场div4

这场比赛除了E题涉及到了一点前缀和以外,其他的应该都是思维题,难度不大,但是想不到的话做起来还是比较吃力。(忽略我菜)

B. Same Parity Summands

题目大意:给两个整数n,k,问n能否由k个整数相加而来,且这k个整数%2的结果相等。

这个题一开始想歪了,其实只要根据奇数+奇数=偶数,偶数+偶数=偶数,奇数+偶数=奇数,这个原则来思考就行,因为这k个整数要么全是奇数,要么全是偶数

所以我们只需要对n和k的奇偶性进行判断

当n为奇数的话,只能是全为奇数才能满足,并且k也要是奇数

n为偶数的话,因为最小的偶数是2,所以当n>2k时,一定满足n可以由k个偶数相加而成

当n<2k时,只能是k个奇数构成,这是也要对k进行奇偶校验。

具体看代码

 1 #include <iostream>
 2 #include <cstring>
 3 #include <string>
 4 #include <algorithm>
 5 #include <queue>
 6 #include <stack>
 7 #include <stdio.h>
 8 #include <cmath>
 9 #include <string.h>
10  
11 using namespace std;
12 #define ll long long
13 static const int WHITE=0;
14 static const int GRAY=1;
15 static const int BLACK=2;
16 static const int INF=0x3f3f3f3f;
17 int gcd(int a,int b){return b == 0 ? a : gcd(b,a%b);}
18 int lcm(int a,int b){return a*b/gcd(a,b);}
19 ll Pow(ll a,ll b,ll mod){if(b==0) return 1%mod; ll sum=1; a=a%mod; while(b>0) { if(b%2==1) sum=(sum*a)%mod; b/=2; a=(a*a)%mod;}return sum;}
20  
21 int main()
22 {
23     //freopen("C:\Users\16599\Desktop\in.txt","r",stdin);
24     int T;
25     cin>>T;
26     while(T--)
27     {
28         ll n,k;
29         cin>>n>>k;
30         if(n<k)
31         {
32             cout<<"NO"<<endl;
33             continue;
34         }
35         if(n%2==1)
36         {
37             if(k%2!=1)
38             {
39                 cout<<"NO"<<endl;
40                 continue;
41             }
42             else
43             {
44                 cout<<"YES"<<endl;
45             for(int i=1;i<=k-1;i++)
46             cout<<"1"<<" ";
47             cout<<n-(k-1)<<endl;                
48             }
49  
50         }
51         else
52         {
53             if(n>=2*k)
54             {
55                 cout<<"YES"<<endl;
56                 for(int i=1;i<=k-1;i++)
57                 cout<<"2"<<" ";
58                 cout<<n-2*(k-1)<<endl;
59             }
60             else
61             {
62                 if(k%2==0)
63                 {
64                     cout<<"YES"<<endl;
65                     for(int i=1;i<=k-1;i++)
66                     cout<<"1"<<" ";
67                     cout<<n-(k-1)<<endl;
68                 }
69                 else
70                 cout<<"NO"<<endl;
71             }
72         }
73     }
74     return 0;
75 }
View Code

E. Special Elements

题目大意,给定一个长度为n的数列,问数列中有多少个元素可以是数列的任意连续子序列的和

只需要求前缀和,将所有可能的连续子序列的和求出来标记,再遍历一遍数列统计个数

需要注意的是这题的内存只有64,所以要根据ai<=n这个条件来进行优化,及如果连续子序列的和都大于n的话,就不需要标记了,一定不存在。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <string>
 4 #include <algorithm>
 5 #include <queue>
 6 #include <stack>
 7 #include <stdio.h>
 8 #include <cmath>
 9 #include <string.h>
10  
11 using namespace std;
12 #define ll long long
13 static const int WHITE=0;
14 static const int GRAY=1;
15 static const int BLACK=2;
16 static const int INF=0x3f3f3f3f;
17 int gcd(int a,int b){return b == 0 ? a : gcd(b,a%b);}
18 int lcm(int a,int b){return a*b/gcd(a,b);}
19 ll Pow(ll a,ll b,ll mod){if(b==0) return 1%mod; ll sum=1; a=a%mod; while(b>0) { if(b%2==1) sum=(sum*a)%mod; b/=2; a=(a*a)%mod;}return sum;}
20 int a[8010],sum[8010];
21 bool v[8010];
22 int main()
23 {
24     //freopen("C:\Users\16599\Desktop\in.txt","r",stdin);
25     int T;
26     cin>>T;
27     while(T--)
28     {
29         int n;
30         cin>>n;
31         for(int i=1;i<=n;i++)
32         {
33             cin>>a[i];
34             sum[i]=sum[i-1]+a[i];
35         }
36         for(int i=0;i<=n;i++)
37         {
38             for(int j=i+2;j<=n;j++)
39             {
40                 if(sum[j]-sum[i]<=n)
41                 v[sum[j]-sum[i]]=true;
42             }
43         }
44         int cnt=0;
45         for(int i=1;i<=n;i++)
46         if(v[a[i]])
47         cnt++;
48         cout<<cnt<<endl;
49         memset(v,false,sizeof(v));
50     }
51     return 0;
52 }
View Code

 F. Binary String Reconstruction

这一题我个人认为是最难想且坑点最多的题了,我也是看了别人的思路才会写的

题目大意,给定三个数n0,n1,n2,构造一个01串,并且这个串满足有n0个"00",n1个"01"或"10",n2个"11"。

构造方法 由于n0和n2只有0和1所以如果他们同时存在,则必有一个n1,所以先判断n1是否存在

n1若存在,则通过11110000这种先1后0的形式处理完n0和n2,最后只要在后面加01即可

 1 #include <iostream>
 2 #include <cstring>
 3 #include <string>
 4 #include <algorithm>
 5 #include <queue>
 6 #include <stack>
 7 #include <stdio.h>
 8 #include <cmath>
 9 #include <string.h>
10  
11 using namespace std;
12 #define ll long long
13 static const int WHITE=0;
14 static const int GRAY=1;
15 static const int BLACK=2;
16 static const int INF=0x3f3f3f3f;
17 int gcd(int a,int b){return b == 0 ? a : gcd(b,a%b);}
18 int lcm(int a,int b){return a*b/gcd(a,b);}
19 ll Pow(ll a,ll b,ll mod){if(b==0) return 1%mod; ll sum=1; a=a%mod; while(b>0) { if(b%2==1) sum=(sum*a)%mod; b/=2; a=(a*a)%mod;}return sum;}
20  
21 int main()
22 {
23     //freopen("C:\Users\16599\Desktop\in.txt","r",stdin);
24     int T;
25     cin>>T;
26     while(T--)
27     {
28         int n1,n2,n3;
29         cin>>n1>>n2>>n3;
30         if(n2==0)
31         {
32             if(n1!=0)
33             for(int i=0;i<=n1;i++)
34             cout<<"0";
35             if(n3!=0)
36             for(int i=0;i<=n3;i++)
37             cout<<"1";
38             cout<<endl;
39             continue;
40         }
41         n2--;
42         for(int i=0;i<=n3;i++)
43         cout<<"1";
44         for(int i=0;i<=n1;i++)
45         cout<<"0";
46         int now=1;
47         while(n2--)
48         {
49             cout<<now;
50             now^=1;
51         }
52         cout<<endl;
53     }
54     return 0;
55 }
View Code

G. Special Permutation

这题也是一个构造题

 题目大意,给定一个整数n,你需要把1-n的n个整数重新排列,使得到的这个数列相邻两个数的差的绝对值在2-4之间。

由于奇数之间相差为2,偶数之间相差为2,所以分奇偶,从两边同时向中间构造即可,以10为例

10 8 6 4 2 1 3 5 7 9

注意在1和2之间不满足题意,所以在处理这一步的时候只要把2和4换个位置,然后n==2,n==3时特判即可

 1 #include <iostream>
 2 #include <cstring>
 3 #include <string>
 4 #include <algorithm>
 5 #include <queue>
 6 #include <stack>
 7 #include <stdio.h>
 8 #include <cmath>
 9 #include <string.h>
10  
11 using namespace std;
12 #define ll long long
13 static const int WHITE=0;
14 static const int GRAY=1;
15 static const int BLACK=2;
16 static const int INF=0x3f3f3f3f;
17 int gcd(int a,int b){return b == 0 ? a : gcd(b,a%b);}
18 int lcm(int a,int b){return a*b/gcd(a,b);}
19 ll Pow(ll a,ll b,ll mod){if(b==0) return 1%mod; ll sum=1; a=a%mod; while(b>0) { if(b%2==1) sum=(sum*a)%mod; b/=2; a=(a*a)%mod;}return sum;}
20  
21 int main()
22 {
23     //freopen("C:\Users\16599\Desktop\in.txt","r",stdin);
24     int T;
25     cin>>T;
26     while(T--)
27     {
28         int a;
29         cin>>a;
30         if(a==2||a==3)
31         {
32             cout<<"-1"<<endl;
33             continue;
34         }
35         if(a%2==1)
36         {
37             for(int i=a;i>=1;i-=2)
38             cout<<i<<" ";
39             cout<<"4 "<<"2 ";
40             for(int i=6;i<=a;i+=2)
41             cout<<i<<" ";
42         }
43         else
44         {
45             for(int i=a-1;i>=1;i-=2)
46             cout<<i<<" ";
47             cout<<"4 "<<"2 ";
48             for(int i=6;i<=a;i+=2)
49             cout<<i<<" ";
50         }
51         cout<<endl;
52     }
53     return 0;
54 }
View Code
原文地址:https://www.cnblogs.com/zlhdbk/p/12872719.html