题目描述1
Problem - A - Codeforces
题目分析
对于此题我们要求差值种类最大,故我们可以构造出相邻差值分别为1,2,3...由于n规定了最大的范围故我们增到一定的差值之后其差值必定为之前出现过的数字,但由于要保证数组呈递增趋势故可以在(n + i - k) 与 (a[i - 1] + i - 1)中取到最小的那个以保证可以在范围内。
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
void solve()
{
int k, n, d, a[N];
cin >> k >> n;
a[1] = 1;
for(int i = 2; i <= k; i ++)
{
a[i] = min(n + i - k, a[i - 1] + i - 1);
}
for(int i = 1; i <= k; i ++)cout << a[i] << ' ';
cout << '\n';
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t;
cin >> t;
while(t --)
{
solve();
}
return 0;
}
题目描述2
Problem - B - Codeforces
题目分析
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
typedef long long ll;
ll n, a[N], prefix[2][N];
void solve()
{
cin >> n;
for(int i = 1; i <= n; i ++)
{
cin >> a[i];
}
ll ans = 0, cnt1 = 0;
for(int i = 1; i <= n; i ++)
{
if(a[i])cnt1 ++;
else ans += cnt1;//逆序对数量
if(a[i] == 0)prefix[0][i] = prefix[0][i - 1] + 1;
else prefix[0][i] = prefix[0][i - 1];
if(a[i] == 1)prefix[1][i] = prefix[1][i - 1] + 1;
else prefix[1][i] = prefix[1][i - 1];
}
ll sum = ans;
for(int i = 1; i <= n; i ++)
{
if(a[i])//将1改为0
{
ll d = prefix[1][i - 1] - (prefix[0][n] - prefix[0][i]);//左1减右0
ans = max(ans, sum + d);
}
else
{
ll d = (prefix[0][n] - prefix[0][i]) - prefix[1][i - 1];//右0减左1
ans = max(ans, sum + d);
}
}
cout << ans << '\n';
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t;
cin >> t;
while(t --)
{
solve();
}
return 0;
}
题目描述3
Problem - C - Codeforces
题目分析
对于a和c的相对位置是不会发生变化的,其分别可以借助b向右移和左移。
本题确定三点:
1.a,c子序列相等
2.所有a仅右移
3.所有c仅左移
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int n, flag;
char s[N], t[N];
void solve()
{
flag = 0;
string ss = "", tt = "";
cin >> n;
cin >> s + 1 >> t + 1;
for(int i = 1; i <= n; i ++)
{
if(s[i] != 'b')ss += s[i];
if(t[i] != 'b')tt += t[i];
}
if(ss != tt)flag = 1;
if(flag)
{
cout << "NO" << '\n';
return;
}
vector<int> sa, sc, ta, tc;
for(int i = 1; i <= n; i ++)
{
if(s[i] == 'a')sa.push_back(i);
if(s[i] == 'c')sc.push_back(i);
if(t[i] == 'a')ta.push_back(i);
if(t[i] == 'c')tc.push_back(i);
}
flag = 1;
for(int i = 0; i < sa.size() && flag; i ++)
{
if(sa[i] > ta[i])flag = 0;
}
for(int i = 0; i < sc.size() && flag; i ++)
{
if(sc[i] < tc[i])flag = 0;
}
if(!flag)cout << "NO" << '\n';
else cout << "YES" << '\n';
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t;
cin >> t;
while(t --)
{
solve();
}
return 0;
}
题目描述4
cnt[w] : 在w位的数的个数
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
int a[N], cnt[N];
int getpos(int x)
{
int res = 0;
while(x)res ++, x >>= 1;
return res;
}
void solve()
{
int n;
cin >> n;
memset(cnt, 0, sizeof cnt);
for(int i = 1; i <= n; i ++)
{
cin >> a[i];
}
ll ans = 0;
for(int i = 1; i <= n; i ++)
{
int pos = getpos(a[i]);
ans += cnt[pos] ++;
}
cout << ans << '\n';
}
int main()
{
int t;
cin >> t;
while(t --)
{
solve();
}
return 0;
}
题目描述5
Problem - E - Codeforces
题目分析
题意为将相加为t的两个数字尽量分在不同的组中,如果两个数相加为t的只能放在一组的时候,尽量将其平均放置
#include<bits/stdc++.h>
using namespace std;
void solve()
{
int n, t, x;
cin >> n >> t;
for(int i = 1, j = 0; i <= n; i ++)
{
cin >> x;
if((1 + t) / 2 > x)cout << 1 << ' ';
else if(t / 2 < x) cout << 0 << ' ';
else cout << j << ' ', j ^= 1;
}
cout << '\n';
}
int main()
{
int t;
cin >> t;
while(t --)
{
solve();
}
return 0;
}