cpp
#include<bits/stdc++.h>
using namespace std;
void solve()
{
int n,a,cnt=0;
cin>>n;
long long s=0;
for(int i=1;i<=n;i++)
{
cin>>a;
s+=a;
if(a&1)
cnt++;
if(i==1)
cout<<a<<" ";
else
cout<<s-(cnt/3+(cnt%3==1))<<" ";
}
cout<<endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin>>t;
while(t--)
solve();
return 0;
}
上面是修饰过后的代码,感觉非常简短,没用数组啥的,只用了一些变量,一层循环写完了,也没有把过程一步一步分开写
下面是最开始的代码
cpp
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int a[N];//cnt 存奇数的个数
long long s[N];
void solve()
{
int n;
cin>>n;
int cnt=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
s[i]=s[i-1]+a[i];
if(a[i]%2!=0)
cnt++;
if(i==1)
cout<<a[i]<<" ";
else
{
long long ans=s[i];
ans=ans-(cnt/3+(cnt%3==1));
// if(i==4)
// cout<<endl<<"4%3==1的数值是"<<(cnt%3==1)<<endl;
cout<<ans;
if(i!=n)
cout<<" ";
}
}
cout<<endl;
// for(int i=1;i<=n;i++)
// cin>>a[i];
//
// cout<<a[1]<<" ";
//
// int cnt=0;
// for(int i=1;i<=n;i++)
// {
// s[i]=s[i-1]+a[i];
// if(a[i]%2!=0)
// cnt++;
// }
// for(int i=2;i<=n;i++)
// {
// int ans=s[i];
// ans=ans-(cnt/3+(cnt%3==1));
// if(i==2)
// cout<<"i=2的时候奇数的个数是:"<<endl<<cnt<<endl;
// cout<<ans;
// if(i!=n)
// cout<<" ";
// }
// cout<<endl;
//
// memset(a,0,sizeof a);
// memset(s,0,sizeof s);
//memset(cnt,0,sizeof cnt);
//判断奇数偶数个数就行
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin>>t;
while(t--)
solve();
return 0;
}
中间错了几次,主要是因为 long long ,还有我想要用布尔值直接表示,就不需要用一个条件判断,但是之前没有用好,少加了个括号,然后不断输出调试才发现问题
该题我写了好久,看了一下榜单,很多分数很高的人,几分钟就写出了该题
我先是模拟样例理解题意,然后是自己弄几个数据归纳规律
发现全是偶数的话,答案就是总和
两个奇数相加,答案是偶数,两个偶数相加,答案也是偶数,一个奇数一个偶数,这样的组合会让答案减小一
先开始的人要使得答案尽可能大,就是要尽可能避免使用 一个奇数,一个偶数这种组合
另一个人要使得答案尽可能小,就是要尽量使用一个奇数一个偶数的组合,使用一次,可以使得答案减小一,两个奇数的和是偶数,事实上偶数不会影响答案,可以通过模拟样例发现这个规律
我们首先统计奇数的个数,我开始以为是奇数的个数的奇偶性影响答案,试了几个数据发现不是这回事,我试了有7,8,9,10,11,12,13,14,15个奇数对应应该减小的答案,发现是,3,2,3,4,3,4,5,4,5
三个一个循环,想让答案大就每一次操作两个奇数,想让答案小就每次操作一个奇数一个偶数,两个奇数操作后变成了一个偶数,刚好和后面一个奇数操作,这就是博弈!
注意任何操作之后,两个数字都会变成一个偶数,因为向下取整之后乘了二
归纳观察可以发现,奇数出现次数记作 cnt 的话,cnt/3 表示的是需要减少的答案的数目, cnt%3 的结果是 1 的话,表示多了一个奇数,还需要多减小 1 的答案(我的代码里面用了一个比较简短的写法,记得要加括号)
统计奇数个数,a&1 表示的是该数字是奇数,因为二进制表示的话,奇数的二进制的最低位一定是 1 ,1&1==1,偶数的最低位一定是 0,比用模二判断要快一些,因为计算机底层用的是二进制编码
有 1e5 个 1e9 的数字,所以他们的和一定超过了 int 能表示的数据范围,所以要使用 long long