Codeforces Round #713 (Div. 3)
Codeforces Round #713 (Div. 3)
https://codeforces.com/contest/1512
F 好题!
暑假争取天天vp
A. Spy Detected!
pair排序
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
pii a[100];
void solve () {
int n, x = -1, y = -1;
cin >> n;
for (int i = 0; i < n; i ++)
cin >> a[i].first, a[i].second = i;
sort (a, a + n);
if (a[0].first == a[1].first) cout << a[n-1].second + 1 << endl;
else cout << a[0].second + 1 << endl;
}
int main () {
int t;
cin >> t;
while (t --)
solve ();
}
B. Almost Rectangle
分两种情况:
#include <bits/stdc++.h>
using namespace std;
const int N = 405;
char a[N][N];
void solve () {
int n;
cin >> n;
int r1 = -1, c1 = -1, r2 = -1, c2 = -1;
for (int i = 0; i < n; i ++)
for (int j = 0; j < n; j ++) {
cin >> a[i][j];
if (a[i][j] == '*') {
if (r1 == -1) r1 = i, c1 = j;
else if (r2 == -1) r2 = i, c2 = j;
}
}
// cout << r1 << ' ' << c1 << endl;
// cout << r2 << ' ' << c2 << endl;
if (c1 == c2) {
if (c1-1 >= 0) a[r1][c1-1] = '*', a[r2][c2-1] = '*';
else a[r1][c1+1] = '*', a[r2][c2+1] = '*';
}
else if (r2 == r1) {
if (r1-1 >= 0) a[r1-1][c1] = '*', a[r2-1][c2] = '*';
else a[r1+1][c1] = '*', a[r2+1][c2] = '*';
}
else
a[r1][c1] = '*', a[r1][c2] = '*', a[r2][c2] = '*', a[r2][c1] = '*';
for (int i = 0; i < n; i ++) {
for (int j = 0; j < n; j ++)
cout << a[i][j];
cout << endl;
}
}
int main () {
int t;
cin >> t;
while (t --)
solve ();
}
C. A-B Palindrome
根据回文构造的规则,先把可确定的确定下来
然后再从a,b中剩下多的往里面填
注意在途中判断是否回文
#include <bits/stdc++.h>
using namespace std;
void solve () {
int a, b;
cin >> a >> b;
string s;
cin >> s;
int n = a + b;
for (int i = 0; i < n; i ++) {
if (s[i] == '0') a --;
else if (s[i] == '1') b --;
}
for (int i = 0; i <= n-i-1; i ++) {
if (s[i] == '?' && s[n-i-1] == '?') continue;
if (s[i] == '?') {
if (s[n-i-1] == '0') s[i] = '0', a --;
else s[i] = '1', b --;
}
else if (s[n-i-1] == '?') {
if (s[i] == '0') s[n-i-1] = '0', a --;
if (s[i] == '1') s[n-i-1] = '1', b --;
}
}
string t = s;
reverse (t.begin (), t.end ());
if (t != s) {
cout << "-1\n";
return ;
}
if (a == 0 && b == 0) {
cout << s << endl;
return ;
}
for (int i = 0; i <= n-i-1; i ++) {
if (s[i] == '?') {
if (i == n-i-1) {
if (a > 0) a--, s[i] = '0';
else if (b > 0) b --, s[i] = '1';
}
else {
if (a > 1) a -= 2, s[i] = s[n-i-1] = '0';
else if (b > 1) b -= 2, s[i] = s[n-i-1] = '1';
}
}
}
t = s;
reverse (t.begin (), t.end ());
if (t != s) {
cout << "-1\n";
return ;
}
if (a == 0 && b == 0) cout << s << endl;
else cout << "-1\n";
}
int main () {
int t;
cin >> t;
while (t --)
solve ();
}
//a个0,b个1
//t[i]=t[n−i+1]
D. Corrupted Array
vp的时候漏了一种情况
我这里把a[]直接当成b[]输入
先排序,然后前n-1项任选n-2个数之和等于a[n]
要分两种情况考虑
- sum=a[n-1],x在前n-2项中
- sum=a[n-2],x=a[n-1] (别忘了!!)
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 5;
int a[N];
void solve () {
int n;
cin >> n;
n += 2;
int sum = 0;
for (int i = 0; i < n; i ++) cin >> a[i], sum += a[i];
sort (a, a + n);
//sum=a[n-1],x在前n-2项中
sum -= a[n-1];
int id = -1;
for (int i = 0; i < n - 1; i ++) {
int tmp = sum;
tmp -= a[i];
if (tmp == a[n-1]) {
id = i;
break;
}
}
//if (id == -1) cout << -1 << endl;
if (id != -1) {
for (int i = 0; i < n - 1; i ++)
if (i != id) cout << a[i] << ' ';
cout << endl;
return ;
}
//就是漏了这第二种情况
//sum=a[n-2],x=a[n-1]
sum -= a[n-2];
if (sum != a[n-2]) cout << "-1\n";
else {
for (int i = 0; i < n - 2; i ++)
cout << a[i] << ' ';
cout << endl;
}
}
signed main () {
int t;
cin >> t;
while (t --)
solve ();
}
//我这里把a[]直接当成b[]输入
//先排序,然后前n-1项任选n-2个数之和等于a[n]
//要分两种情况考虑
//1. sum=a[n-1],x在前n-2项中
//2. sum=a[n-2],x=a[n-1]
E. Permutation by Sum
贪心的那一步没想到
(可以根据连续的性质来进行贪心分配)
#include <bits/stdc++.h>
using namespace std;
const int N = 505;
bool vis[N];
int n, l, r, s, len;
int ans[N];
void solve () {
memset (vis, false, sizeof vis);
cin >> n >> l >> r >> s;
len = r - l + 1;
int minn = (1+len)*len/2, maxn = (2*n-len+1)*len/2;
//cout << minn << ' ' << maxn << endl;
if (s < minn || s > maxn) {
cout << "-1\n";
return ;
}
//1-n中选len个数,和为s
//贪心找即可
//将s与minn做差,得dx,从后往前均摊dx个
int cnt = 0; //统计minn与s平均分配了多少次
while (minn + (cnt + 1) * len <= s && len + (cnt + 1) <= n)
cnt ++; //最多能整体偏移多少
int dx = s - (minn + cnt * len); //记录不能被均分的差
//cout << "dx: " << dx << endl;
for (int i = l; i <= r; i ++) {
int j = (i - l + 1) + cnt;
if (i > r - dx) j ++; //后dx项再++
if (!vis[j]) {
ans[i] = j;
vis[j] = true;
}
}
int k = 1;
for (int i = 1; i <= n; i ++) {
if (vis[i]) continue;
while (k >= l && k <= r) k ++;
ans[k ++] = i;
}
// if (dx > len) {
// cout << "-1\n";
// return ;
// }
// //更新[l,r]
// //1 2 ...
// for (int i = l, j = 1; i < l + len - dx; i ++, j ++) {
// pos[j] = 1;
// ans[i] = j;
// }
// //...(偏移后的后半段)
// for (int i = r, j = len + 1; i >= l + len - dx; i --, j --) {
// pos[j] = 1;
// ans[i] = j;
// }
// int k = 0;
// for (int i = 1; i <= n && k < l ; i ++) {
// if (pos[i] == 1) continue;
// pos[i] = 1;
// ans[++ k] = i;
// }
// k = r;
// for (int i = 1; i <= n && k <= n ; i ++) {
// if (pos[i] == 1) continue;
// pos[i] = 1;
// ans[++ k] = i;
// }
for (int i = 1; i <= n; i ++) cout << ans[i] << ' ';
cout << endl;
}
int main () {
int t;
cin >> t;
while (t --)
solve ();
}
F. Education
两种操作:
- 拿当日工资
- 不拿工资,花b[i]提升阶层(改变第二天的工资)
dp,不会
点击前往学习
小心爆int!!!
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 5;
int f[N][2], a[N], b[N], res[N];
void solve () {
int n, c;
cin >> n >> c;
for (int i = 1; i <= n; i ++) cin >> a[i];
for (int i = 1; i < n; i ++) cin >> b[i];
for (int i = 1; i <= n; i ++) {
f[i][0] = f[i-1][1] + (int)ceil(1.0*(c-res[i])/a[i]);
f[i][1] = f[i-1][1] + (int)ceil(1.0*(b[i]-res[i])/a[i]) + 1;
res[i+1] = res[i] + a[i]*(int)ceil(1.0*(b[i]-res[i])/a[i])-b[i];
}
int ans = 0x3f3f3f3f;
for (int i = 1; i <= n; i ++) ans = min (ans, f[i][0]);
cout << ans << endl;
}
signed main () {
int t; cin >> t;
while (t --) {
solve ();
}
}
//注意这里的除都是上取整
//f[i][0] = f[i-1][1] + (c-res[i])/a[i]
//f[i][1] = f[i-1][1] + (b[i]-res[i])/a[i] + 1
//res[i+1] = res[i] + a[i]*((b[i]-res[i])/a[i])-b[i]
G. Short Task
n的所有因子之和等于c,求最小的n
打表
#include <bits/stdc++.h>
using namespace std;
const int N = 1e7;
int ans[N+1], a[N+1];
//暴力打表
void pre () {
for (int i = 1; i <= N; i ++) { //第一个因子
for (int j = i; j <= N; j += i)
a[j] += i; //第二个因子
if (a[i] <= N && ans[a[i]] == 0)
ans[a[i]] = i;
}
for (int i = 1; i <= N; i ++)
if (ans[i] == 0) ans[i] = -1;
}
void solve () {
int n;
cin >> n;
cout << ans[n] << endl;
}
int main () {
pre();
int t;
cin >> t;
while (t --) solve ();
}
//先-1,得质数直接输出
//否则继续分解到质数因子