正睿20秋季提高十连测day3

估分: 100 + 0 + 30 = 130

实际: 80 + 0 +30 =110

T1:

  错题原因:m=0没特判(虽然题目出毛病说m是正整数)

  对于任意一个无向图,都能去掉<m/2的边使他变成一个二分图,当然一条边都没有的情况除外,所以除了m=0的情况输出一个Yes就行了。至于怎么证明,找不到反例就是对的

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 int main()
 8 {
 9     int n, m;
10     scanf("%d%d", &n, &m);
11     for (int i = 1; i <= m; i++)
12     {
13         int a, b;
14         scanf("%d%d", &a, &b);
15     }
16     if (m) puts("Yes");
17     else puts("No");
18 }
View Code

 

T2:

   不会,写乱搞算法然而没对。

  因为是取反,所以操作顺序没影响,可以把两个字符串转换成在最小化1的数量的基础上最小化1的下标的字典序,然后看一不一样。至于怎么转换,一个1前面有k个0,就一定能把这个1向前移动k位。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 inline int read()
 8 {
 9     int x = 0, f = 0;
10     char ch = getchar();
11     while (!isdigit(ch)) f = ch == '-', ch = getchar();
12     while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
13     return f ? -x : x;
14 }
15 
16 const int N = 1000010;
17 
18 int n, k;
19 int c[N];
20 char b[N];
21 char str[N], ed[N];
22 
23 string get(char s[])
24 {
25     string res = "";
26     if (k == 1) return res;
27 
28     int cnt = 0;
29     for (int i = 1; i <= n; i++)
30     {
31         if (cnt && b[cnt] == s[i])
32         {
33             if (++c[cnt] == k) cnt--;
34         }
35         else b[++cnt] = s[i], c[cnt] = 1;
36     }
37 
38     for (int i = 1; i <= cnt; i++)
39     {
40         for (int j = 1; j <= c[i]; j++) res += b[i];
41     }
42 
43     return res;
44 }
45 
46 int main()
47 {
48     int T = read();
49     while (T--)
50     {
51         n = read(), k = read();
52         scanf("%s%s", str + 1, ed + 1);
53         puts(get(str) == get(ed) ? "Yes" : "No");
54     }
55 }
View Code

 

T3:

  不会,暴了30pts的力

   将属于S中的数p排列,可行的公差只有所有p[i]-p[i-1]的最大公约数的因数,求出来然后枚举判断当前公差是否可行,如果可行答案要加上小于等于p[1]可以放入S中的数的个数乘以大于等于p[n]的可以放入S中的数的个数

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 typedef long long LL;
 8 
 9 const int N = 100010;
10 const LL mod = 1e9 + 7;
11 
12 LL n, m;
13 LL ans, cnt1, cnt2;
14 LL bel[N], nobel[N];
15 
16 bool cmp(LL a, LL b)
17 {
18     return a < b;
19 }
20 
21 LL gcd(LL a, LL b)
22 {
23     return b ? gcd(b, a % b) : a;
24 }
25 
26 void check(LL x)
27 {
28     LL l = (bel[1] - 1) % x + 1, r = bel[1] + (n - bel[1]) / x * x;
29     for (int i = 1; i <= cnt2; i++)
30     {
31         LL p = nobel[i];
32         if (p % x != bel[1] % x) continue;
33         if (p >= bel[1] && p <= bel[cnt1]) return;
34         if (p < bel[1]) l = p + x;
35         else if (p - x < r) r = p - x;
36     }
37     LL L = (bel[1] - l) / x + 1, R = (r - bel[cnt1]) / x + 1;
38     ans = (ans + L % mod * (R % mod)) % mod;
39 }
40 
41 int main()
42 {
43     scanf("%lld%lld", &n, &m);
44     for (int i = 1; i <= m; i++)
45     {
46         LL flag, x;
47         scanf("%lld%lld", &flag, &x);
48         if (flag) bel[++cnt1] = x;
49         else nobel[++cnt2] = x;
50     }
51 
52     sort(bel + 1, bel + cnt1 + 1, cmp);
53     sort(nobel + 1, nobel + cnt2 + 1, cmp);
54 
55     LL tol = 0;
56     for (int i = 2; i <= cnt1; i++)
57     {
58         tol = gcd(tol, bel[i] - bel[i - 1]);
59     }
60 
61     for (LL i = 1; i * i <= tol; i++)
62     {
63         if (tol % i) continue;
64         check(i);
65         if (i * i != tol) check(tol / i);
66     }
67 
68     printf("%lld", ans);
69 }
View Code

 

总结:

  就只会第一题送分题,第二题是完全没想到这个东西,一直在想怎么把第一个字符串转换为第二个,还是要多换几种角度方法考虑,第三题想到了正解的一部分,其实是能写50pts或70pts的暴力的,但把时间大部分花在了第二题上,没多管第三题,后面时间就不够写更好的暴力了,时间还是要注意分配,下意识的觉得第三题很难就没多注意。

 

posted on 2020-09-14 11:29  ArrogHie  阅读(164)  评论(0)    收藏  举报