https://codeforces.com/contest/1701
A
只有四种情况:
0 0 1 0 1 0 1 1 1 1
0 0 0 0 0 1 1 0 1 1
由于一次可以删除一行一列,所以总的分为3种情况:
1:四个数和为0,需要0次;
2:四个数和为1-3,需要一次;
3:四个数和为4,需要2次;
#include<iostream>
#include<string>
using namespace std;
int main()
{
int t;
cin >> t;
while (t--)
{
int num, sum = 0;
for(int i=0;i<2;i++)
for (int j = 0; j < 2; j++)
{
cin >> num;
sum += num;
}
if (sum == 0)
cout << 0 << endl;
else if (sum == 4)
cout << 2 << endl;
else
cout << 1 << endl;
}
return 0;
}
B
要使得满足条件的相邻数最多,d只能取2(列举一段数据比较d=2/3/4的情况可得)。又数据只能由1-n且不重复的数字组成,因此输出序列可如(n=10)——‘1 2 4 8’ ‘3 6’ ‘5 10’ 7 9 ‘’部分可换位置
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
bool book[200005];
int main()
{
int t;
cin >> t;
while (t--)
{
int n;
cin >> n;
memset(book, 0, n + 1);
cout << 2 << endl;
for (int i = 1; i <= n / 2; i++)
{
if (book[i])
continue;
int num = i;
while (num <= n)
{
cout << num << ' ';
book[num] = 1;
num *= 2;
}
}
for (int i = n / 2 + 1; i <= n; i++)
if (!book[i])
cout << i << ' ';
cout << endl;
}
return 0;
}
C
经典二分求最大化最小值
最小时间为1,最大时间为任务数m2,设左右边界l=1,r=2m,二分找到能完成所有任务的选定时间。
记选定时间为t,用a记录多的任务量,b记录少的能分配的任务量,book记录编号为i的员工擅长任务的总量
初始状态——每个员工统计的任务量都是他们擅长的,能以时间1完成的
a+=book[i]-t即为在t时间内完成不了(多出来)的任务数量
b+=(t-book[i])/2即为员工能完成的分配的(不擅长)的任务数量(由于员工完成不擅长任务需要时间2,因此计算能完成的任务量时要/2)
#include<iostream>
using namespace std;
typedef long long ll;
int book[200005];
int main()
{
int t;
cin >> t;
while (t--)
{
int n, m, num;
cin >> n >> m;
memset(book, 0, sizeof(book));
for (int i = 0; i < m; i++)
{
cin >> num;
book[num]++;
}
int l = 0, r = 2 * m;
while (l < r)
{
int mid = (l + r) / 2;
ll a = 0, b = 0;
for (int i = 1; i <= n; i++)
{
if (book[i] > mid)
a += book[i] - mid;
else
b += (mid - book[i]) / 2;
}
if (a >b)
l = mid + 1;
else
r = mid;
}
cout << l << endl;
}
return 0;
}