Codeforces Round #705 (Div. 2)A-C
Codeforces Round #705 (Div. 2)
打的异常痛苦的一把CF,总结原因如下:
- 题意没有审清,过度借助翻译软件,以后要渐渐开始阅读英文题面
- 比赛时间记错,导致比赛开始五分钟后才进场,状态没有调整过来
争取能够改正。
A. Anti-knapsack
给定整数n, k, 要求输出一个集合,该集合满足一下条件:
- 集合中的元素满足[1, n]。
- 任意子集中元素的和不等于k。
只要保证创造出的集合中的元素都大于\(\left \lceil k/2 \right \rceil\)并且小于等于n即可
#include<bits/stdc++.h>
#define ll int
using namespace std;
const int maxn = 2e5 + 5;
ll read(){
char ch=getchar();
ll x=0,f=1;
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=getchar();
return x*f;
}
void solve(){
ll n = read(), m = read();
cout << n - m/2 - (m%2 == 1)<< endl;
for (int i = m/2 + (m%2 == 1); i <= n; i++) if(i != m) cout << i << " ";
cout << endl;
}
int main(){
int t;cin>>t;
while(t--){
solve();
}
}
B. Planet Lapituletti
在另外一个星球上,有一些时间和我们不一样的外星人。他们的一天只有h小时m分钟,他们常常通过镜子看时钟上的时间,如果他们看到他们的时间是符合他们的常识的,他们就会感到高兴。
比如:12:21,在他们的镜子上看起来就像是 15:51(沿竖轴对称)。如果他们h > 15 && m > 51即可满足条件(这里wa了好多次)
首先明确:只有当正常的时间由数字0, 1, 2, 5, 8组成时,在镜子上才是正常的数字,其次,只要满足它们对称后的数字在一天的时间以内即可。
给定h, m,和现在的时间,要求输出下一个会让外星人感到高兴的时间。挂四层暴力即可
#include<bits/stdc++.h>
#define ll int
using namespace std;
const int maxn = 2e5 + 5;
ll read(){
char ch=getchar();
ll x=0,f=1;
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=getchar();
return x*f;
}
int turn(int a)
{
if (a == 2) return 5;
if (a == 5) return 2;
return a;
}
void solve(){
ll h = read(), m = read();
ll nh, nm, a[5] = {0, 1, 2, 5, 8};
scanf("%d:%d", &nh, &nm);
for (int i = 0; i < 5; i++)
for (int j = 0; j < 5; j++)
for (int k = 0; k < 5; k++)
for (int l = 0; l < 5; l++)
if (a[i] * 10 + a[j] < h && a[k] * 10 + a[l] < m
&& (a[i] * 10 + a[j]) * m + a[k] * 10 + a[l] >= nh * m + nm
&& turn(a[l]) * 10 + turn(a[k]) < h && turn(a[j]) * 10 + turn(a[i]) < m)
{cout << a[i] << a[j] << ":" << a[k] << a[l] << endl; return;}
cout << "00:00" << endl;
}
int main(){
int t;cin>>t;
while(t--){
solve();
}
}
C. K-beautiful Strings
给定字符串s和长度n以及数字k,要求找到字典序大于等于s的最小的等长字符串,满足该字符串中每个字母出现的次数都整除k。
首先,若n%k!=0,则必定不存在字符串。否则必定存在最大字符串zzz...满足条件。
因为题目条件与字母出现的次数有关,因此不妨令cnt\(_{i}\)代表某一字母出现的次数。
对于每个字母i来说,它还需要出现 \(\mathit{(k-cnt_{i} \bmod {k}) \bmod {k}}\) 次。若需要改造整个字符串,则最少需要改\(
\sum_{1}^{26} (k - cnt_{i} \bmod {k}) \bmod {k}\)个字母
因此,从后往前枚举(保证最小字典序),然后对每一个字母c从c+1开始遍历所有字母,并验证是否能够更改(即更改之后能够改造它及以后所有的字母来满足条件),具体看代码。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll read(){
char ch=getchar();
ll x=0,f=1;
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=getchar();
return x*f;
}
int f(char c)
{
return c - 'a';
}
void solve()
{
ll n = read(), k = read(), cnt[30];
char s[100003];
scanf("%s", s + 1);
if (n % k)
{
puts("-1");
return;
}
memset(cnt, 0, sizeof(cnt));
int ret = 0;//需要改造的字符总数
for (int i = 1; i <= n; i++)
{
cnt[f(s[i])]++;
}
for (int i = 0; i < 26; i++)
{
ret = ret + (k - cnt[i] % k) % k;
}
if (ret == 0)//若不需要改造
{
printf("%s", s + 1);
puts("");
return;
}
for (int i = n; i >= 1; i--)
{
cnt[f(s[i])]--;//对于s上的某一个字母,先删掉
if (cnt[f(s[i])] % k == 0)ret -= k - 1;
else ret++;
int g = ret;
for (int j = f(s[i]) + 1; j < 26; j++)
{
ret -= (k - cnt[j] % k) % k;
cnt[j]++;
ret += (k - cnt[j] % k) % k;
if (n - i >= ret && (n - i - ret) % k == 0)
{
for (int h = 1; h < i; h++)
{
printf("%c", s[h]);
}
printf("%c", j + 'a');
for (int h = 1; h <= (n - i - ret); h++)
{
printf("a");
}
for (int h = 0; h < 26; h++)
{
for (int o = 1; o <= (k - cnt[h] % k) % k; o++)
{
printf("%c", h + 'a');
}
}
puts("");
return;
}
ret = g;
cnt[j]--;
}
}
}
int main()
{
int t;
cin >> t;
while (t--)
{
solve();
}
}

浙公网安备 33010602011771号