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