Educational Codeforces Round 20
Educational Codeforces Round 20
昨天写的
https://codeforces.com/contest/803
笨比只会AB
CD 其实都是很基础的题目,但是我脑瘫,总是一堆问题。
C是不停的溢出,ll也不够,这涨了个经验就是,比较不等式的时候尽量用除,减少溢出的可能性。思维上也是还差了一步,就是gcd一定要是n的因子,这是TLE的最主要原因!!也是临门一脚了
D就是差一步转化的过程,还有一些边界的细节问题www anyway我真的好粗心啊qaq
A. Maximal Binary Matrix
码力太弱,写的时候要想好久好久
#include <bits/stdc++.h>
using namespace std;
const int N = 105;
int a[N][N];
int main () {
int n, k;
cin >> n >> k;
if (k > n * n) cout << -1;
else {
//n,n-1,n-2,...,1
for (int i = 1; i <= n; i++) {
//(i,i)开始
if (k <= 0) break;
a[i][i] = 1, k --;
for (int j = i + 1; j <= n; j++) {
if (k <= 0) break;
if (k == 1) {
a[i+1][i+1] = 1, k --;
break;
}
a[j][i] = a[i][j] = 1;
k -= 2;
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cout << a[i][j] << ' ';
}
cout << endl;
}
}
}
//奇数填边角
//偶数对角线
B. Distances to Zero
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
int a[N], pre[N], n;
int main () {
cin >> n;
set<int> s;
int maxn = -1e9;
for (int i = 1; i <= n; i++) {
cin >> a[i];
if (a[i] == 0) s.insert (i), maxn = i;
pre[i] = maxn;
}
for (int i = 1; i <= n; i++) {
if (a[i] == 0) cout << 0 << ' ';
else {
auto it2 = s.upper_bound (i);
int l = pre[i], r = 1e9;
if (it2 != s.end ()) r = *it2;
//cout << l << ' ' << r << endl;
cout << min (i - l, r - i) << ' ';
}
}
}
//找到最近0
C. Maximal GCD
枚举 + 数学
总是溢出麻了。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll sum, k;
bool check (ll x) {
//x,2x,3x,4x,...
//cout << x << ' ' << base * x << endl;
//base * x > sum的拆解
if ((k * x) / 2 > sum / (k + 1)) return false;
//多出来的全部放到最后
for (ll i = 1; i < k; i++) printf ("%lld ", x * i);
ll cnt = sum / x - 1ll * k * (k - 1) / 2;
printf ("%lld\n", cnt * x);
return true;
}
int main () {
scanf ("%lld%lld", &sum, &k);
//base = k * (k + 1) / 2;
//cout << base << endl;
if (k > (2 * sum) / (k + 1)) {
printf ("-1");
return 0;
}
//必须得是n的因子才可以
vector <ll> v;
v.push_back (1);
for (ll i = 2; i * i <= sum; i++) {
if (sum % i == 0) {
v.push_back (i);
if (i != sum / i) v.push_back (sum / i);
}
}
sort (v.begin (), v.end (), greater<ll>());
//for (auto i : v) cout << i << ' ';cout << endl;
for (auto i : v) {
if (check (i)) return 0;
}
printf ("-1");
}
//枚举gcd来check
//明明和题姐写的一样,恼
//gcd必须要是sum的因子
//注意比大小问题, 不等式尽量除来比大小,ll都会溢出啊啊啊啊
D. Magazine Ad
基础二分题
// LUOGU_RID: 102831150
#include <bits/stdc++.h>
using namespace std;
string s;
vector<int> a;
int k;
bool check (int len) { //check以len为最大长度,会不会超过k行
int cnt = 1, sum = 0;
//不能截断完整的单词
//cout << len << ": ";
for (auto i : a) {
if (i > len) return false;
if (sum + i <= len) sum += i; //还能塞的下一行
else cnt ++, sum = i; //换行
//cout << sum << ' ';
}
if (cnt > k) return false;
return true;
}
int main () {
cin >> k;
getchar ();
getline (cin, s);
//cout << s;
//cout << s.size () << endl;
//预处理每一整段的长度
int len = 0;
for (int i = 0; i < s.size (); i++) {
len ++;
if (s[i] == ' ' || s[i] == '-') a.push_back (len), len = 0;
}
if (len) a.push_back (len);
//for (auto i : a) cout << i << ' ';cout << endl;
int l = 1, r = s.size ();
while (l < r) {
int mid = l + r >> 1;
if (check (mid)) r = mid;
else l = mid + 1;
//cout << endl;
}
cout << r << endl;
}
//二分最大切割长度
//最大值最小
//二分但是check的函数不会写
//呃呃其实非常的板啊!!我是sb
//直接记录一段的长度即可, 把字符串按照长度划分为ai