Educational Codeforces Round 107 (Rated for Div. 2)题解
题目链接
被B题卡到了,唉,还是自己人傻逼。
A题
题意:有三种类型的客人,他们依次到来,一种反对者,一种支持者,还一种观望者,即根据当前情况,如果反对数 > 支持数,就投反对,反之投支持的人,现在你有两个投票系统,你可以选择给当前来到的客人展示其中一种,问你最多可以获得多少票支持。
思路:显然就是支持者数目 + 观望者数目, 因为显然我们可以让反对只投到一个投票系统上。
int main()
{
IOS;
int T;
cin >> T;
while(T --)
{
int n;
cin >> n;
int up = 0, down = 0;
for(int i = 0 ; i < n ; i ++)
{
int r;
cin >> r;
if(r == 1) up ++;
else if(r == 2) down ++;
else up ++;
}
cout << up << "\n";
}
return 0;
}
B题
题意:给三个数\(a, b, c\), 让你找到两个数\(x\)和\(y\),使得\(x,y,gcd(x, y)\)这三个数的位数分别是\(a,b,c\)。
思路:显然是一个构造题,想办法构造即可。
我开始没写程序检验,想当然以为是对了,卡了半天,还wa了4发,心疼。
我构造的是往数的末尾添3和7的方法,但是注意\(gcd(1003, 17) = 17\)这个唯一的坑爹情况(下面的三目运算用途正是如此),由于数据范围不大,这种可以自己打表检验规避!!!
代码如下
int base[11];
int main()
{
IOS;
int T;
cin >> T;
base[1] = 0;
int t = 1;
for(int i = 2 ; i <= 10 ; i ++)
t = t * 10, base[i] = t;
while(T --)
{
int a, b, c;
cin >> a >> b >> c;
int x;
if(a == 1) x = 1;
else x = (base[a - c + 1] + (a >= b ? 7 : 3)) * (base[c] ? base[c] : 1);
int y;
if(b == 1) y = 1;
else y = (base[b - c + 1] + (b > a ? 7 : 3)) * (base[c] ? base[c] : 1);
cout << x << " " << y << endl;
}
return 0;
}
C题
题意:从前往后给你n张卡片,每个卡片都有一个颜色,然后有m次询问,每次询问找到最前面的这个颜色的卡片,输出它的下标,然后把它放到最开头去。
思路:由于卡片的颜色最多只有50种,显然我们只需要维护每种颜色最前面的卡片即可,因为后面的没有意义,我们从前面拿一张放到开头去,它的下标没有变化。
代码如下
int n, q;
int idx[55];
int main()
{
IOS;
cin >> n >> q;
for(int i = 1 ; i <= n ; i ++)
{
int x;
cin >> x;
if(!idx[x]) idx[x] = i;
}
while(q --)
{
int p;
cin >> p;
cout << idx[p] << " ";
for(int i = 1 ; i <= 50 ; i ++)
if(idx[i] < idx[p])
idx[i] ++;
idx[p] = 1;
}
return 0;
}
D题
题意:让你用从'a'开始的前k个字母,构造一个字符串S(此处下标从1开始),使得满足\(1 <= i < j <= len(S),S_i = S_j , S_{i + 1} = S_{j + 1}\)的\({i, j}\)对数最少。
思路:我们以双字符组成的串来看,可以选择hash把它们映射成\(0到675\)的数,根据上一个字母枚举当前字母,选择当前字母能构成的之前出现次数最少的双字符,每次尽量选择较后的字母,因为我们是从前往后枚举的,这样能最大化预留之后的选择空间。
代码如下
int cnt[700];
char s[N];
int main()
{
IOS;
int n, k;
cin >> n >> k;
s[0] = 'a';
int last = 0;
for(int i = 1 ; i < n ; i ++)
{
int mind = 1e9, d = -1;
for(int j = 0 ; j < k ; j ++)
{
if(mind >= cnt[last * 26 + j])
{
mind = cnt[last * 26 + j];
d = j;
}
}
cnt[last * 26 + d] ++;
last = d;
s[i] = d + 'a';
}
for(int i = 0 ; i < n ; i ++)
cout << s[i];
return 0;
}
E题
想了半个小时也没想出来,后面再补。
题意:
思路:
代码如下

浙公网安备 33010602011771号