Codeforces Round #654 (Div. 2) DEF
D
题目
思路
只需要选择不选择相邻的就行了,最后可以形成(n+1)/2个数相加
延长两倍之后选择即可
代码
#include <iostream>
#include <cstdio>
#include <set>
#include <list>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <string>
#include <sstream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <fstream>
#include <iomanip>
//#include <unordered_map>
using namespace std;
#define dbg(x) cerr << #x " = " << x << endl;
typedef pair<int, int> P;
typedef long long ll;
#define FIN freopen("in.txt", "r", stdin);
const int MAXN = 305;
int a[MAXN][MAXN];
void print(int n)
{
cout << "--------------------------" <<endl;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
cout << a[i][j];
}
cout << endl;
}
cout << "--------------------------" << endl;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
int n, k;
while(t--)
{
memset(a, 0, sizeof(a));
cin >> n >> k;
ll ans = 0;
if(k % n == 0)
{
ans = 0;
}
else
{
ans = 2;
}
int p = 0, q = 0;
while(k--)
{
a[p][q] = 1;
p++, q++, q %= n;
if(p == n)
{
p = 0, q++, q %= n;
}
}
/* int maxx = -1, minn = 0x3f3f3f3f;
for(int i = 0; i < n; i++)
{
int cnt = 0;
for(int j = 0; j < n; j++)
{
if(a[i][j]) cnt++;
}
maxx = max(maxx, cnt);
minn = min(minn, cnt);
}
ans = (maxx - minn) * (maxx - minn);
maxx = -1, minn = 0x3f3f3f3f;
for(int i = 0; i < n; i++)
{
int cnt = 0;
for(int j = 0; j < n; j++)
{
if(a[j][i]) cnt++;
}
maxx = max(maxx, cnt);
minn = min(minn, cnt);
}
ans += (maxx - minn) * (maxx - minn);
cout << ans << endl;*/
cout << ans << endl;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
cout << a[i][j];
}
cout << endl;
}
}
return 0;
}
E
题目
思路
没什么思路,但是其实看到这个数据范围应该想到dp的,只是区间dp做的确实少,不大会
dp[l][r]代表l~r列的分数,对中间每一列k进行一次dp
方程dp[l][r] = max(dp[l][r], dp[l][k-1] + dp[k+1][r] + cnt*cnt)
cnt是处在l~r区间的行区间数
代码
#include <iostream>
#include <cstdio>
#include <set>
#include <list>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <string>
#include <sstream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <fstream>
#include <iomanip>
//#include <unordered_map>
using namespace std;
#define dbg(x) cerr << #x " = " << x << endl;
typedef pair<int, int> P;
typedef long long ll;
#define FIN freopen("in.txt", "r", stdin);
const int MAXN = 1e2+5;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n, m;
cin >> n >> m;
ll left[MAXN][MAXN] = {0}, right[MAXN][MAXN] ={0}, dp[MAXN][MAXN] = {0};
for(int i = 1; i <= n; i++)
{
int k;
cin >> k;
while(k--)
{
int ll, rr;
cin >> ll >> rr;
for(int j = ll; j <= rr; j++)
{
left[i][j] = ll;
right[i][j] = rr;
}
}
}
for(int l = m; l >= 1; l--)
{
for(int r = l; r <= m; r++)
{
for(int k = l; k <= r; k++)
{
ll cnt = 0;
for(int i = 1; i <= n; i++)
{
if(left[i][k] >= l && right[i][k] <= r)
{
cnt++;
}
}
dp[l][r] = max(dp[l][r], dp[l][k-1] + dp[k+1][r] + cnt*cnt);
}
}
}
cout << dp[1][m] << endl;
return 0;
}
F
题目
思路
交互题,每次询问一个区间,会告诉你这个区间出现最多的数字和出现的次数,给出一个符合要求的非递减序列
对于询问的区间l, r,每次会给你一个出现最多的数字x和次数f,那么我们就观察这个f,如果这个f大于(l + r)/ 2,那么我们必能确定在l到r有一个小区间里面都是x,小区间的左右端点是r-f+1和l+f-1,这样我们填写小区间之后,再询问小区间左右的数字即可
代码
```cpp
#include <iostream>
#include <cstdio>
#include <set>
#include <list>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <string>
#include <sstream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <fstream>
#include <iomanip>
//#include <unordered_map>
using namespace std;
#define dbg(x) cerr << #x " = " << x << endl;
typedef pair<int, int> P;
typedef long long ll;
#define FIN freopen("in.txt", "r", stdin);
const int MAXN = 2e5+5;
int a[MAXN];
P ask(int l, int r)
{
cout << "? " << l << ' ' << r << endl;
int x, f;
cin >> x >> f;
return P(x, f);
}
void solve(int l, int r)
{
//dbg(l);
//dbg(r);
if(l > r) return;
int x, f;
P tmp;
tmp = ask(l, r);
x = tmp.first;
f = tmp.second;
int rr = l + f - 1, ll = r - f + 1;
if(ll <= rr)
{
for(int i = ll; i <= rr; i++)
{
a[i] = x;
}
//cout << "OK" <<endl;
solve(l,ll-1);
solve(rr+1, r);
}
else
{
int mid = (l + r) >> 1;
solve(l, mid);
solve(mid+1, r);
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n;
cin >> n;
solve(1, n);
cout << "! ";
for(int i = 1; i <= n; i++)
{
cout << a[i] << ' ';
}
cout << endl;
return 0;
}