Codeforces Round #561 (Div. 2) 题解
A. Silent Classroom
水题。
Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 105;
int n;
char s[N], t[N];
int main() {
cin >> n;
for(int i = 1; i <= n; i++) {
scanf("%s", t + 1);
s[i] = t[1] ;
}
sort(s + 1, s + n + 1) ;
int cnt = 0;
int ans = 0;
for(int i = 1; i <= n + 1; i++) {
if(s[i] != s[i - 1]) {
if(cnt == 0) cnt = 1;
else {
int tmp = cnt / 2;
ans += tmp * (tmp - 1) / 2 + (cnt - tmp) * (cnt - tmp - 1) / 2;
cnt = 1;
}
} else cnt++;
}
cout << ans ;
return 0;
}
B. All the Vowels Please
满足行列都大于5就行了,后面乱构造一下就好了。
代码如下:
Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 105;
int n;
char s[N] = {'0', 'a', 'e', 'i', 'o', 'u'} ;
int main() {
cin >> n;
int r, c = -1;
for(int i = 5; i < n; i++) {
if(n % i == 0 && n / i >= 5) {
r = i;
c = n / i;
break ;
}
}
if(c == -1) {
cout << -1;
return 0;
}
for(int i = 1; i <= r; i++) {
int k = (i - 1) % 5 + 1;
for(int j = 1; j <= c; j++) {
cout << s[(j + k - 2) % 5 + 1] ;
}
}
return 0;
}
C. A Tale of Two Lands
比赛时硬生生分情况讨论...最后可能是因为细节原因还是没有A出来。好吧傻逼了。
对于(|x|,|y|)来说,(x,y)的正负并不会产生什么影响;对于(|x-y|,|x+y|)来说,(x,y)的正负也不会产生什么影响。所以我们就可以直接对(a_i)取绝对值,只看为正数的情况就好了。
然后就随便推一下,把绝对值去掉就行了。
代码如下:
Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 5;
int n;
ll a[N], b[N];
int main() {
ios::sync_with_stdio(false); cin.tie(0) ;
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i], b[i] = a[i] < 0 ? -a[i] : a[i] ;
sort(b + 1, b + n + 1) ;
ll ans = 0;
int l = 1, r = 2;
while(r <= n) {
while(l < r && b[l] * 2 < b[r]) l++;
ans += r - l;
r++;
}
cout << ans;
return 0;
}
D. Cute Sequences
这个题上午把我整自闭了...还是细节方面没有处理好。
首先可以推出(x_n=2^{n-2}*a+2^{n-3}*r_2+cdots+2*r_{n-2}+r_{n-1}+r_n),因为(1leq rleq m),我们可以知道如果存在一个(n)满足条件,那么有(2^{n-2}*(a+1)leq bleq 2^{n-2}*(a+m)),通过这个来判断是否存在合理情况就行了。我一开始判断这里的时候爆long long了。。。也搞了我半天。
之后我们就开始构造方案,首项为(a),我们先令(r_i=1),那么此时最大项的值就为(2^{n-2}*(a+1)),现在要做的就是改变某些(r_i)的值,使得最后最大项等于(b)。
令(R=b-2^{n-2}*(a+1)),根据我们之前推出来的式子,可以知道(r_i)之前的系数为(2^{n-i-1}),贪心来构造的话就是每次找到一个最大的(X),满足(X*2^{n-i-1}leq R 且 (X+1)*2^{n-i+1}>R),并且(1leq Xleq m),然后每次令(r_i)等于(X)即可。
这样来构造的话最后是肯定保证有解的。
代码如下:
Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 105;
const ll MAX = 1e14 ;
ll q, a, b, m;
ll r[N] ;
ll qp(ll A, ll B) {
ll ans = 1;
while(B) {
if(B & 1) ans = ans * A;
A = A * A;
B >>= 1;
}
return ans ;
}
int main() {
ios::sync_with_stdio(false); cin.tie(0) ;
cin >> q;
while(q--) {
memset(r, 0, sizeof(r)) ;
cin >> a >> b >> m;
if(a == b) {
cout << 1 << ' ' << a << '
' ;
continue ;
}
int p = -1;
for(int i = 2; i <= 50; i++) {
if(qp(2, i - 2) * (a + 1) > MAX) break ;
if(qp(2, i - 2) * (a + 1) <= b && qp(2, i - 2) * (a + m) >= b) {
p = i;
break ;
}
}
if(p == -1) {
cout << -1 << '
';
continue ;
}
ll R = b - qp(2, p - 2) * (a + 1);
ll S = a;
for(int i = 2; i < p; i++) {
ll now = qp(2, p - i - 1) ;
ll x = min(R / now, m - 1) ;
r[i] = x;
}
S = a;
cout << p << ' ' << S << ' ';
for(int i = 2; i < p; i++) {
cout << S + r[i] + 1 << ' ' ;
S += S + r[i] + 1;
}
cout << b << '
' ;
}
return 0;
}
E. The LCMs Must be Large
这是个很有意思的题。首先很容易证明如果存在两天,在这两天中得到的数字集合不存在交集,那么肯定是无解的。
主要就是证明两两天数之间存在交集时,为什么一定方案有解。
可以这样来构造,如果在第(j)天去了({a_1,a_2,cdots,a_k})这些商店,那么我们将这些位置的数都乘以第(j)个质数。
最后如果两两天数之间存在交集的话,那么它们的lcm肯定为所有质数的乘积,而它们补集的lcm肯定不存在当前天的质数。
所以这种构造方案就可以保证任意两天存在交集时是一定有解的。
由于(m)的范围很小,所以求是否有交时暴力一下就行了。
代码如下:
Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M = 55, N = 1e4 + 5;
int m, n;
int s[N] ;
vector <int> v1[N], v2[M] ;
bool vis[M] ;
int main() {
ios::sync_with_stdio(false); cin.tie(0);
cin >> m >> n;
for(int i = 1; i <= m; i++) {
int x, y;
cin >> x;
for(int j = 1; j <= x; j++) {
cin >> y;
v1[y].push_back(i) ;
v2[i].push_back(y) ;
}
}
int ok = 1;
for(int i = 1; i <= m; i++) {
memset(vis, 0, sizeof(vis)) ;
int cnt = 0;
for(auto other : v2[i]) {
for(auto v : v1[other]) {
if(!vis[v]) vis[v] = 1, cnt++;
}
}
if(cnt < m) {
ok = 0;
break ;
}
}
if(ok) cout << "possible" ;
else cout << "impossible";
return 0;
}