A. Median Maximization
这道题就是一简单的思维题,直接放代码
#include <iostream>
#include <cstdio>
using namespace std;
const int N = 1e4 + 10;
int main()
{
int T;
cin >> T;
while(T--)
{
int n, s;
scanf("%d%d", &n, &s);
if(n % 2 == 0)
{
int t = n / 2;
cout << s / (n - t + 1) << endl;
}
else
{
int t = n / 2 + 1;
cout << s / (n - t + 1) << endl;
}
}
return 0;
}
B. MIN-MEX Cut
b题一开始理解错了,以为字串是可以不连续的,
字串:在字符串取出一块连续的
子序列:在字符串中顺序取出,但是可以不连续
那么接下来就可做了,首先我们知道不管怎么样,答案是不会超过2的,所以我们可以贪心的枚举该字符串,然后判断是否超过2,
参考代码:
#include <iostream>
using namespace std;
int main()
{
int T;
cin >> T;
while(T--)
{
string s;
cin >> s;
int ans = 0;
for(int i = 0; i < s.size() - 1; i++)
{
if(s[i] != s[i + 1])
{
if(s[i] == '0') ans += 1;
else if(s[i] == '1') ans += 0;
}
}
if(s[s.size() - 1] == '0') ans += 1;
else ans += 0;
if(ans >= 2) cout << "2" << endl;
else cout << ans << endl;
}
return 0;
}
C. MAX-MEX Cut
这题在比赛是没做出来,不知道为什么第8个测试点超时了,早上起来补题时发现,忘记我这个做法如果全为1时,时间复度为 O(n ^ 2),然后优化了一下,发现就过了,好可惜呀
参考代码:
#include <iostream>
using namespace std;
int main()
{
int T;
cin >> T;
while(T--)
{
int n;
string s1, s2;
cin >> n >> s1 >> s2;
int ans = 0;
for(int i = 0; i < n; i++)
{
if(s1[i] != s2[i]) ans += 2;
else
{
if(s1[i] == '1')
{
int j;
for(j = i + 1; j < n; j++)
{
if(s1[j] == s2[j] && s1[j] == '0')
{
ans += 2;
i = j;
break;
}
if(s1[j] != s2[j])
{
i = j - 1;
break;
}
}
if(j == n) break;
}
else
{
if(s1[i + 1] == s2[i + 1] && s1[i + 1] == '1')
{
ans += 2;
i++;
}
else ans += 1;
}
}
}
cout << ans << endl;
}
return 0;
但出于代码的简洁性,下面为官方代码:
#include <iostream>
#include <algorithm>
using namespace std;
int slove(string s)
{
int sum = count(s.begin(), s.end(), '0');
bool flag1 = false, flag2 = false;
for(int i = 0; i < s.size(); i++)
{
if(s[i] == '1') flag1 = true;
if(s[i] == '0') flag2 = true;
if(flag1 && flag2)
{
sum++;
flag1 = flag2 = false;
}
}
return sum;
}
int main()
{
int T;
cin >> T;
while(T--)
{
int n;
string a, b, s;
cin >> n >> a >> b;
int ans = 0;
for(int i = 0; i < n; i++)
{
if(a[i] != b[i])
{
ans += 2 + slove(s);
s = "";
}
else s += a[i];
}
cout << ans + slove(s) << endl;
}
return 0;
}
D1. Seating Arrangements (easy version)
这题,没什么好说,暴力就完事
参考代码:
#include <iostream>
using namespace std;
const int N = 310;
int a[N][N];
int main()
{
int T;
cin >> T;
while(T--)
{
int n, m;
cin >> n >> m;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++) cin >> a[i][j];
int ans = 0;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
int t = 0;
for(int k = 1; k < j; k++)
{
if(a[i][k] < a[i][j]) t++;
}
ans += t;
}
}
cout << ans << endl;
}
return 0;
}
D2. Seating Arrangements (hard version)
这题是D1的困难版,当时做这题时,已经很晚了,然后看了下,发现时间可能不够(还有20分钟结束),然后就去睡觉了
然后早上起来补题,发现好像不是特别难,就是排序的问题,
先排一次序,确定这些人怎么安排,在根据下标排一次序,累加答案,当然有些小细节需要注意一下,就是第一次排序时,但2个数相等时,下标小的在前面,这样才能确保答案最小
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
struct stu
{
int w, id;
}a[N];
bool cmp1(stu x, stu y)
{
if(x.w == y.w) return x.id < y.id;
return x.w < y.w;
}
bool cmp2(stu x ,stu y)
{
return x.id < y.id;
}
int main()
{
int T;
cin >> T;
while(T--)
{
int n, m;
cin >> n >> m;
for(int i = 1; i <= n * m; i++) cin >> a[i].w, a[i].id = i;
sort(a + 1, a + n * m + 1, cmp1);
int ans = 0;
for(int i = 0; i < n; i++)
{
int t = 1 + i * m;
sort(a + t, a + m + t, cmp2);
for(int j = t; j <= (i + 1) * m; j++)
{
for(int k = t; k < j; k++)
if(a[k].w < a[j].w) ans++;
}
}
cout << ans << endl;
}
return 0;
}
总结:
总的来说这场cf好像并不是特别的难,但是需要手速(hh),感觉自己对有些概念和库函数还不是非常熟悉,所以以后得更加努力的写题,看课。
count()库函数:
count(a.begin(), a.end(), s); s为需要统计的数或字符