目录
题目:
Dashboard - Educational Codeforces Round 131 (Rated for Div. 2) - Codeforces
A. Grass Field
题意:
2X2的01矩阵中, 每一次可以把一行+一列的1换成0,问最少多少次可以把全部涂成0?
思路:
显然分以下三种情况
1)全部是0直接输出0
2)全部是1直接输出2(如第一次选i=1,j=1, 则第二次只要选到了i=2/j=2就能达成目标)
3)乱七八糟的其他情况, 自己举例子就会发现, 只要是一个到三个都可以用涂1次来达成目标!
code:
/**
* author: CurleyD
* created: 07.08.2022 22:36:07
**/
#include <bits/stdc++.h>
#define endl '\n'
#define IO ios::sync_with_stdio(false); cin.tie(nullptr);
using namespace std;
typedef long long LL;
//#define LOCAL
//#define int LL
//head
const int N = 1e5 + 10;
int T, n, m;
void solve() {
int cnt1 = 0;
for (int i = 1; i <= 2; i++) {
for (int j = 1; j <= 2; j++) {
cin >> m;
if (m == 1)
cnt1++;
}
}
if (cnt1 == 0)
cout << "0\n";
else if (cnt1 == 4)
cout << "2\n";
else
cout << "1\n";
}
signed main() {
IO;
#ifdef LOCAL
freopen("out.txt","w",stdout);
#endif
cin >> T;
while(T--) {solve();}
return 0;
}
B. Permutation
题意:
给你一个长度为n的排列, 由1~n组成, 你可以任选一个d(0~n之间), and排列的代价为排列中满足的数量.
思路:
解读题目 : 比如n=4 排列为 1 2 4 3 我们选择d = 2 满足上述条件的由 i = 1, i = 2, i = 3. 代价是3
显然, 要想让上述的代价最大我们就要让相邻的满足倍数关系, 并且这个倍数关系要尽可能的小, 才能让更多的i满足这个条件使得代价更大! 类似这样 1 2 4 3 6 9 4 8 16.........
code:
/**
* author: CurleyD
* created: 07.08.2022 22:36:06
**/
#include <bits/stdc++.h>
#define endl '\n'
#define IO ios::sync_with_stdio(false); cin.tie(nullptr);
using namespace std;
typedef long long LL;
//#define LOCAL
//#define int LL
//head
const int N = 1e5 + 10;
int T, n, m;
void solve() {
cin >> n;
map<int,int> mp;
cout << "2\n1 ";
for (int i = 2; i <= n; i++) {
for (int j = i; j <= n; j*=2) {
if (mp[j] != 1) {
cout << j << " ";
mp[j] = 1;
}
}
}
cout << endl;
}
signed main() {
IO;
#ifdef LOCAL
freopen("out.txt","w",stdout);
#endif
cin >> T;
while(T--) {solve();}
return 0;
}
C. Schedule Management
题意:
n个工人, m个工作, 每个工作对应着适合它的工人, 这个工作如果让适合他的人来做所花费的时间是1单位时间, 让其他人做花费时间是2单位时间, 问最小花费时间?
思路:
开始一直没思路, 剩2分钟结束我突然发现是个二分答案题, 但来不及写了..., 为什么是二分呢? 暴力等各种模拟绝对会T/WA的毋庸置疑, 结合题目中给的数据范围那剩下的不就是二分了吗?操作如下:
1)记录每个工人的完成时间
2)按照大到小/小到大sort以下便于二分
3)二分 + check(mid),
4)check函数用的是所有工人总共欠的时间和0进行比较
比如1号工人完成所有他要做的任务需要10单位时间 结果当前check函数中的x是2那么1号工人就相当于欠了(10-x)单位时间, 因此欠的(10-x)单位时间的任务就要分担到别人身上, 这里要注意分到别人身上不是每个任务1单位时间了, 而是要乘2. 当然也要注意分给其他人时候别溢出!
所有的加和后如果不欠时间(sum <= 0), 就证明工人们可以互相交换穿插任务之后完成这些个任务!!!
对了, 如果按我这么实现记得开long long 我的实现会爆int, 原因懒得想了em..., 睡觉了...
code:
/**
* author: CurleyD
* created: 07.08.2022 23:22:03
**/
#include <bits/stdc++.h>
#define endl '\n'
#define IO ios::sync_with_stdio(false); cin.tie(nullptr);
using namespace std;
typedef long long LL;
//#define LOCAL
//#define int LL
//head
const int N = 1e5 + 10;
int T, n, m;
int a[200005];
int cs[200005];
int check(int x) {
LL sum = 0;
for (int i = 1; i <= n; i++) {
if (cs[i] > x) {
sum += cs[i] - x;
}
else {
sum -= (x - cs[i]) / 2;
}
}
if (sum > 0)
return 0;
else
return 1;
}
void solve() {
memset(cs, 0, sizeof cs);
int res = 0;
cin >> n >> m;
for (int i = 1; i <= m; i++) {
cin >> a[i];
cs[a[i]] ++;
res = max(cs[a[i]], res);
}
sort(cs + 1, cs + 1 + n);
int l = 1, r = 2e5 + 10;
//二分答案->最大工作时间
while (l < r) {
int mid = l + r >> 1;
if (check(mid))
r = mid;
else
l = mid + 1;
//cout<<l<<" "<<r<<endl;
}
cout << l << endl;
}
signed main() {
IO;
#ifdef LOCAL
freopen("out.txt","w",stdout);
#endif
cin >> T;
while(T--) {solve();}
return 0;
}
OS:
前两天摆烂就是玩, 脑子比较木, 签到A卡了10min才出结论... B读完题就想到了正解, 但代码实现居然在各个小点出问题了, WA了三发??? 不太理解啊, 看来真是得天天干.... 做完AB看了C的题目没什么眉目, 很久没写二分了也没第一时间想到, 坐牢1.25小时后发现正解, 但来不及在比赛时候写了, 梦回省赛二分没写出来......