849div4
题意:
给定一个数组,一个操作可以讲i和i+1两数变为相反数,任意次操作,最大的数组和是多少
思路:
负数的个数,无论两数有多远,都可以把他俩都变为相反,负数为偶数,那么就是绝对值的和,负数为奇数,那么就减去绝对值最小的那个数的两倍绝对值
代码:
#include <bits/stdc++.h>
using i64 = long long;
void solve() {
int n;
std::cin >> n;
i64 sum = 0;
int neg = 0;
std::vector<int> a(n);
for (int i = 0; i < n; i++) {
std::cin >> a[i];
if (a[i] < 0) {
neg++;
a[i] = -a[i];
}
sum += a[i];
}
if (neg % 2 == 1) {
int mn = *std::min_element(a.begin(), a.end());
sum -= 2 * mn;
}
std::cout << sum << "\n";
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t;
std::cin >> t;
while (t--) {
solve();
}
return 0;
}
847div3
C. Premutation
题意:给一个大小为n序列的n个长度为n-1的子串,还原原序列
思路:第一位最多的那个数字就是第一位数字,后面为不存在第一位数字的那个子串
代码:
#include<bits/stdc++.h>
using namespace std;
void solve();
int main(){
int t;
cin>>t;
while (t--){
solve();
}
}
void solve(){
int b[105];
memset(b,0,sizeof b);
int n;
int a[105][105];
cin>>n;
for (int i = 0; i < n; ++i) {
for (int j = 0; j <n-1 ; ++j) {
cin>>a[i][j];
}
}
char k;
for (int i = 0; i <n ; ++i) {
b[a[i][0]]++;
}
int ks,hm;
for (int i = 1; i <=n ; ++i) {
if(b[i]>1)
ks=i;
if(b[i]==1)
hm=i;
}
cout<<ks;
for (int i = 0; i < n; ++i) {
if(a[i][0]==hm){
for (int j = 0; j <n-1 ; ++j) {
cout<<' '<<a[i][j];
}
break;
}
}
cout<<endl;
}
D. Matryoshkas
题意:
给一个大小为n的数组,问最少需要多少个从一开始的连续序列组成这个数组
思路:
可用map,自动排序,记录每个数的个数 遍历map,如果这个数x不等于pre+1,则cnt+=c(x的个数);如果等于pre+c,如果x【c】>pre【c】,则cnt+=x【c】-pre【c】
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int t,n;
int main(){
cin>>t;
while (t--){
cin>>n;
int ans=0;
map<ll,ll>m;
for (int i = 0; i <n ; ++i) {
ll x;
cin>>x;
m[x]++;
}
ll prex=-1,prec;
for (auto [x,c]:m) {
if(x!=prex+1)
ans+=c;
else if(c>prec)
ans+=c-prec;
prex=x,prec=c;
}
cout<<ans<<endl;
}
return 0;
}