Codeforces Goodbye 2019

题目链接:https://codeforces.com/contest/1270


A:

白给

 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define dou double
 6 #define pb emplace_back
 7 #define mp make_pair
 8 #define sot(a,b) sort(a+1,a+1+b)
 9 #define rep1(i,a,b) for(int i=a;i<=b;++i)
10 #define rep0(i,a,b) for(int i=a;i<b;++i)
11 #define eps 1e-8
12 #define int_inf 0x3f3f3f3f
13 #define ll_inf 0x7f7f7f7f7f7f7f7f
14 #define lson (curpos<<1)
15 #define rson (curpos<<1|1)
16 /* namespace */
17 using namespace std;
18 /* header end */
19 
20 int t;
21 
22 int main() {
23     cin >> t;
24     while (t--) {
25         int n, k1, k2;
26         cin >> n >> k1 >> k2;
27         int maxA = 0, maxB = 0;
28         for (int i = 1; i <= k1; i++) {
29             int x; cin >> x; maxA = max(maxA, x);
30         }
31         for (int i = 1; i <= k2; i++) {
32             int x; cin >> x; maxB = max(maxB, x);
33         }
34         if (maxA > maxB) puts("YES"); else puts("NO");
35     }
36     return 0;
37 }
View Code

B:

这道题很容易被绕进暴力验证的坑,然后发现只能O(n^2)做,过不了。

设数组A[l..r]最大值为Ai,最小值为Aj(暂定i<j,反之亦然),若数组A满足interesting,则有Ai-Aj>=r-l+1>=abs(i-j)+1。展开不等式左边,则有(Ai-Ai+1)+(Ai+1-Ai+2)+...+(Aj-1-Aj)>=abs(i-j)+1,则必有一组相邻的数,其差的绝对值>=2。故只要O(n)扫一遍作差即可。

 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define pb emplace_back
 6 #define mp make_pair
 7 #define eps 1e-8
 8 #define lson (curpos<<1)
 9 #define rson (curpos<<1|1)
10 /* namespace */
11 using namespace std;
12 /* header end */
13 
14 const int maxn = 2e5 + 10;
15 int t, n, a[maxn];
16 
17 int main() {
18     scanf("%d", &t);
19     while (t--) {
20         int p = -1, q = -1;
21         scanf("%d", &n);
22         for (int i = 1; i <= n; i++) {
23             scanf("%d", &a[i]);
24             if (i == 1) continue;
25             if (abs(a[i] - a[i - 1]) >= 2) p = i - 1, q = i;
26         }
27         if (p == -1) puts("NO");
28         else printf("YES
%d %d
", p, q);
29     }
30     return 0;
31 }
View Code

C:

纯数学题。定义数组和为S,异或和为X,只需要加上X和S+X即可。左边=S+X+(S+X)=2(S+X),右边=X^X^(S+X)=S+X,满足题意。

 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define pb emplace_back
 6 #define mp make_pair
 7 #define eps 1e-8
 8 #define lson (curpos<<1)
 9 #define rson (curpos<<1|1)
10 /* namespace */
11 using namespace std;
12 /* header end */
13 
14 int t,n;
15 
16 int main() {
17     scanf("%d",&t);
18     while (t--){
19         scanf("%d",&n);
20         ll sum=0, k;
21         for (int i=0;i<n;i++){
22             ll x; scanf("%lld",&x);
23             sum+=x;
24             if (!i) k=x; else k^=x; 
25         }
26         if (sum==2*k) puts("0
");
27         else printf("2
%lld %lld
",k,sum+k);
28     }
29     return 0;
30 }
View Code

D:

非常有趣的交互题。题意如下:

有一个长度为n的int类型数组a,其元素未知。最多可进行n次查询,每次查询给出不超过k个下标,返回这k个下标对应数的第m大数(m未知)的下标和值。求m。

其实这个题样例的做法已经是正解:无论n多长,只研究前k+1个数。查询k+1次,每个数都忽略一次,查询其他数,这样得到的查询结果只会出现第m个数和第m+1个数(且后者严格大于前者)。第m+1个数一定会出现m次(在他前面的数都被忽略过一次),第m个数会出现若干次,只需要输出第m+1个数的次数即可。

 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define pb emplace_back
 6 #define mp make_pair
 7 #define eps 1e-8
 8 #define lson (curpos<<1)
 9 #define rson (curpos<<1|1)
10 /* namespace */
11 using namespace std;
12 /* header end */
13 
14 int n, k, maxx = 0;
15 map<int, int>cnt;
16 
17 int main() {
18     cnt.clear();
19     scanf("%d%d", &n, &k);
20     for (int i = 1; i <= k + 1; i++) {
21         printf("?");
22         for (int j = 1; j <= k + 1; j++) {
23             if (i == j) continue;
24             printf(" %d", j);
25         }
26         puts("");
27         fflush(stdout);
28         int pos, val;
29         scanf("%d%d", &pos, &val);
30         cnt[val]++; maxx = max(maxx, val);
31     }
32     printf("! %d
", cnt[maxx]);
33     fflush(stdout);
34     return 0;
35 }
View Code
原文地址:https://www.cnblogs.com/JHSeng/p/12309298.html