比赛链接;
A
核心思路:其实我们不要被迷惑了,这就是一个构造题。如果遇到构造题没有思路的话。可以联想经典的构造。也就是一大一小进行构造。然后检查是否可行。
// Problem: A. Make it Beautiful
// Contest: Codeforces - Educational Codeforces Round 141 (Rated for Div. 2)
// URL: https://codeforces.com/contest/1783/problem/0
// Memory Limit: 512 MB
// Time Limit: 3000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=100;
int a[N],sum[N];
void solve()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
int flag=1;
sort(a+1,a+1+n);
for(int i=1;i<=n-1;i++)
{
if(a[i]!=a[i+1])
flag=0;
}
if(flag)
{
cout<<"NO"<<endl;
return;
}
cout<<"YES"<<endl;
vector<int> ans;
for(int i=1;i<=n/2;i++)
cout<<a[i]<<" "<<a[n+1-i]<<" ";
if(n%2)
cout<<a[n/2+1];
cout<<endl;
}
int main()
{
int T;
cin>>T;
while(T--)
{
solve();
}
}
B
核心思路:这个题目感觉挺没有水准的,可以说纯靠猜吧。属于u那种比赛打多了进行的积累。主要是题目所给的样例不好直接猜测,也就是一大一小构造,采用的是蛇形路径。只能说多积累吧。莫得办法。
// Problem: B. Matrix of Differences
// Contest: Codeforces - Educational Codeforces Round 141 (Rated for Div. 2)
// URL: https://codeforces.com/contest/1783/problem/B
// Memory Limit: 256 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e3+10;
int ans[N][N];
void solve()
{
int n;
cin>>n;
int l=1;
int r=n*n;
int cnt=0;
for(int i=1;i<=n;i++)
{
if(i&1)
{
for(int j=1;j<=n;j++,cnt++)
{
if(cnt&1)
ans[i][j]=r--;
else
ans[i][j]=l++;
}
}
else
{
for(int j=n;j>=1;j--,cnt++)
{
if(cnt&1)
ans[i][j]=r--;
else
ans[i][j]=l++;
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
cout<<ans[i][j]<<" ";
cout<<endl;
}
}
int main()
{
int T;
cin>>T;
while(T--)
{
solve();
}
}
C
核心思路:
D
核心思路:这题其实比较难看来是一个dp,但是我们可以通过模拟样例发现性质。分析这个转换之后的数组a'.我们对于最后一个位置a'[i].
a[i-2] a[i-1] a[i]
4 5 6
a'[i-2] a'[i-1] a'[i]
-1 5 11
所以有这个递推关系:\(a'[i]-a[i]=a'[i-1]\),所以我们就知道了数组中的a'[i-1]表示的是什么了, 因为我们的a数组是已知的,然后我们不断地往前面倒推可以得出来a'数组。
这里表示的其中一种关系.
所以我们就可以得出我们dp的状态定义了。
状态定义:\(f[i][j]\)表示的是我们对于前i个数进行操作后最后一个数是j的方案数
状态划分:首先我们需要知道的是这是一个i线性dp,所以我们直接利用最后一个状态和前面一个状态的关系进行划分。
我们可以根据我们的a'数组是怎么转变过来的来进行划分。很显然可以分为两种情况:
- 由最后一数加j
- 有最后一个数减j
分析完总体框架之后就来分析代码中的细节:
首先可以存在数组越界的情况,所以我们需要再加一个偏移量。
然后就是枚举的范围,我们需要知道的是我们数据的一个极限范围是每个数都是300,
先看个例子吧:300 300 300 300,我们会发现最后一个数的上界的极限范围是900.也就是300*4-300.所以我们枚举的范围也就确定了。
#include<bits/stdc++.h>
using namespace std;
const int N = 310, B = 300 * 300, D = B , INF = 0x3f3f3f3f;
const int mod = 998244353;
int a[N];
int f[N][B * 2 + 10];
void solve()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++ ) cin >> a[i];
f[2][a[2] + D] = 1;
for (int i = 2; i < n; i++ ) {
for (int j = -B + 300; j <= B - 300 ; j++ ) {
if (j) {
f[i + 1][a[i + 1] - j + D] = (f[i + 1][a[i + 1] - j + D] + f[i][j + D]) % mod;
f[i + 1][a[i + 1] + j + D] = (f[i + 1][a[i + 1] + j + D] + f[i][j + D]) % mod;
} else {
f[i + 1][a[i + 1] + D] = (f[i + 1][a[i + 1] + D] + f[i][j + D]) % mod;
}
}
}
int ans = 0;
for (int i = -B; i <= B; i++ )
ans = (ans + f[n][i + D]) % mod;
cout << ans << endl;
}
signed main()
{
ios::sync_with_stdio(0),cin.tie(0);
// freopen("input.txt", "r", stdin);
int T = 1;
// cin >> T;
while(T -- ) solve();
}
标签:Educational,Rated,141,int,Codeforces,300,solve,--,我们
From: https://www.cnblogs.com/xyh-hnust666/p/17041689.html