题目描述1
Problem - A - Codeforces
题目分析
通过题目发现a[1] = d[1],
a[i] = d[i] + a[i - 1]
由于所有的数都为正数,所以只要出现a[i - 1] - d[i] >= 0这种情况a[i]就可以取为绝对值,也就是说a[i]会有一正一负两种情况,当然,如果在这个a[i - 1] - d[i] >= 0条件我们要保证d[i]是不为0的不然正负都是只有一种情况
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int d[N], a[N];
void solve()
{
int n;
memset(d, 0, sizeof d);
memset(a, 0, sizeof a);
cin >> n;
for(int i = 1; i <= n; i ++)cin >> d[i];
a[1] = d[1];
for(int i = 2; i <= n; i ++)
{
a[i] = d[i] + a[i - 1];
if(d[i] && a[i - 1] - d[i] >= 0)
{
cout << - 1 << '\n';
return;
}
}
for(int i = 1; i <= n; 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
题目分析
我们最终的目的是为了升序排序,且其操作为反转操作,故我们从数组两边使用双指针,遇到01需要进行反转的就停下做出一次记录(此处使用vector)即可,注意输出时从小到大即可,所以需要排序
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
void solve()
{
char a[N];
int n, flag = 0;
cin >> n;
for(int i = 1; i <= n; i ++)
{
cin >> a[i];
}
for(int i = 2; i <= n; i ++)
{
if(a[i - 1] > a[i])flag = 1;
}
if(!flag)
{
cout << 0 << '\n';
}
else
{
vector<int> v;
int l = 1, r = n;
while(l < r)
{
while(l < r && a[l] == '0')l ++;
while(l < r && a[r] == '1')r --;
if(l < r)
{
v.push_back(l);
v.push_back(r);
l ++;
r --;
}
}
sort(v.begin(), v.end());
cout << 1 << '\n' << v.size() << ' ';
for(auto i : v)
{
cout << 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;
}
题目描述3
Problem - C - Codeforces
题目分析
将10拆解成2和5,因为只有2 * 5可以拆解成10,如果少2就乘2或者少5就乘5,如果还可以继续就乘10,由于此时末尾都为0,故还可以乘到小于m的倍数
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
void solve()
{
ll n, m;
cin >> n >> m;
ll k = 1;
ll t = n;
ll c2 = 0, c5 = 0;
while(t % 2 == 0)t /= 2, c2 ++;
while(t % 5 == 0)t /= 5, c5 ++;
while(c2 < c5 && k * 2 <= m)k *= 2, c2 ++;
while(c5 < c2 && k * 5 <= m)k *= 5, c5 ++;
while(k * 10 <= m)k *= 10;
cout << n * k * (m / k) << '\n';
}
int main()
{
int t;
cin >> t;
while(t --)
{
solve();
}
return 0;
}
题目描述4
Problem - D - Codeforces
题目分析
对于此题主要是数的配对,我们将数都存入map将数组排序,从大到小来看每一个数,如果其数/x在map中还存在说明这两个数字可以配对,将这个数字以及可以和这个数配对的数字删除,如果说没有可以/x的数说明不能配对此时就需要添加数字用ans记录添加的个数
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
void solve()
{
int ans = 0;
int n, x;
map<int, int> mp;
int a[N];
cin >> n >> x;
for(int i = 1; i <= n; i ++)
{
cin >> a[i];
mp[a[i]] ++;
}
sort(a + 1, a + 1 + n);
for(int i = n; i >= 1; i --)
{
if(mp[a[i]])
{
if(a[i] % x == 0)
{
if(mp[a[i] / x] == 0)
{
ans ++;
mp[a[i]] --;
}
else
{
mp[a[i]] --;
mp[a[i] / x] --;
}
}
else
{
mp[a[i]] --;
ans ++;
}
}
}
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;
}
题目描述5
Problem - E - Codeforces
题目分析
我们可以将每一列存在vector中进行计算,使用下方的区间模型将答案加入ans
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<vector<ll>> v;
void solve()
{
int n, m, x;
ll ans = 0;
cin >> n >> m;
v.clear();
v.resize(m + 1);
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= m; j ++)
{
cin >> x;
v[j].push_back(x);
}
}
for(int i = 1; i <= m; i ++)
{
sort(v[i].begin(), v[i].end());
for(int j = 1; j < n; j ++)
{
ans += 1ll * (v[i][j] - v[i][j - 1]) * j * (n - j);
}
}
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;
}