C. Good Array
想不出很好的方法,目前写的都是TLE,两种,有一种大二的姐姐写了AC的码
//AC
#include <iostream>
#include <cstring>
#include <algorithm>
#include<stdio.h>
#define int long long
using namespace std;
int ai[200010];
int s1[200010];
int s2[200010];
int ans[200010];
signed main()
{
int n;
cin >> n;
int sum=0;
int cnt=0;
for(int i=1;i<=n;i++)
{
cin >> ai[i];
sum+=ai[i];
}
for(int i=1;i<=n;i++)
{
s1[i]=max(s1[i-1],ai[i]);
}
for(int i=n;i>=1;i--)
{
s2[i]=max(s2[i+1],ai[i]);
}
for(int i=1;i<=n;i++)
{
if((sum-ai[i]-max(s1[i-1],s2[i+1])==max(s1[i-1],s2[i+1])))
{
ans[++cnt]=i;
}
}
cout << cnt<<endl;
if(cnt!=0)
{
for(int i=1;i<=cnt-1;i++)
cout << ans[i]<<" ";
cout << ans[cnt]<<endl;
}
return 0;
}
//TLE
#include<stdio.h>
#include<algorithm>
using namespace std;
struct node{
int num,site;
}s[1000000];
bool cmp(node a,node b)
{
return a.num<b.num;
}
int n,sum=0,j=0,ans=0,b[50000];
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&s[i].num);
s[i].site=i+1;
}
sort(s,s+n,cmp);
for(int i=0;i<n;i++) sum=sum+s[i].num;
while(j<n-1){
for(int i=0;i<n;i++){
if(i==n-1-j) continue;
if(sum-s[i].num==2*s[n-1-j].num){
ans++;
b[ans]=s[i].site;
}
}
j++;
}
if(ans){
printf("%d\n",ans);
for(int i=1;i<=ans;i++){
printf("%d ",b[i]);
}
}
else printf("0\n");
}
//TLE
#include<stdio.h>
#include<algorithm>
#include<iostream>
using namespace std;
#define N 10000111
int a[N],b[N],s[N],i,j,t,n,m,q,sum=0,ans=0;
int main()
{
cin>>n;
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
b[i]=a[i];
sum=sum+a[i];
}
sort(a,a+n+1); //wrong
ans=0;
for(j=0;j<=n;j++)
for(i=1;i<=n;i++){
if(a[i]==a[n-j]) continue;
if(sum-a[i]==2*a[n-j]){
// ans++;
for(t=1;t<=n;t++){
if(a[i]==b[t]){
ans++;
s[ans]=t;
b[t]=-1;
}
}
}
}
if(ans){
printf("%d\n",ans);
for(int i=1;i<=ans;i++){
printf("%d ",s[i]);
}
}
else printf("0\n");
}
爱丽丝和鲍勃从他们的父母那里得到了n块糖果。每颗糖重1克或2克。现在他们想公平地分配所有糖果这样爱丽丝的糖果的总重量就等于鲍勃的糖果的总重量。看看他们能不能做到注意糖果是不允许被切成两半的。输入第一行包含一个整数(1 <t< 104)——测试用例的数量。接下来是测试用例。* X每个测试用例的第一行包含一个整数(1<n<100)——Alice和Bob收到的糖果数量。下一行包含n个整数al, a2, ..,即糖果的重量。每个糖果的重量不是1就是2它保证所有测试用例的n之和不超过105
题意:给你一堆由面值为1或2的硬币,问你能不能把这堆硬币分成两堆,使得两堆硬币面值和相同。
可以发现如果硬币和如果是奇数,无法平均分配(硬币无法锯开~),然后在和为偶数的前提下,如果面值为2的硬币数量为奇数,面值为1的硬币数量为0,那也是无法平均分配的。剩下的情况下就是2的数量为偶数(包括0),1的数量为偶数辣,肯定能平均分。
(如果2的数量是偶数1的数量是奇数就无法满足和为偶数了~)
这种写法更省时不用一段一段打printf,后面注释的思路有点问题,做题不要太投机取巧。
#include <stdio.h>
#define N 10000111
using namespace std;
#include <algorithm>
int a[N],b[N],i,j,t,n,sum,flag=0;
int main()
{
scanf("%d",&t);
while(t--){
int c1=0,c2=0;
flag=0;
sum=0;
scanf("%d",&n);
for(i=0;i<n;i++) scanf("%d",&a[i]);
for(i=0;i<n;i++) sum=sum+a[i];
for(i=0;i<n;i++){
if(a[i]==1) c1++;
else c2++;
}
if(sum%2==0){
if(c1==0){
if(c2%2==0) flag++;
}else flag++;
}
if(flag) printf("YES\n");
else printf("NO\n");
}
}
//if(sum%2!=0){
// printf("NO\n");continue;
// }
// if(sum%2==0&&n%2==0){
// printf("YES\n");continue;
// }
// if(n%2!=0&&sum%4==0) printf("YES\n");
// else printf("NO\n");
AcWing 795. 前缀和
输入一个长度为n的整数序列。
接下来再输入m个询问,每个询问输入一对l, r。
对于每个询问,输出原序列中从第l个数到第r个数的和。
// 用前缀和思想,从角标1开始存储;
// s[i]存储的就为a[1]至a[i]的和;
// 求l至r即为s[r]-s[l-1]
#include <stdio.h>
#define N 10000111
using namespace std;
#include <algorithm>
int a[N],s[N],i,j,t,n,m,sum=0,flag=0;
int main()
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++) scanf("%d",&a[i]);
for(i=1;i<=n;i++) s[i]=s[i-1]+a[i];
// 用前缀和思想,从角标1开始存储;
// s[i]存储的就为a[1]至a[i]的和;
// 求l至r即为s[r]-s[l-1].
int l,r;
while(m--){
sum=0;
scanf("%d%d",&l,&r);
printf("%d\n",s[r]-s[l-1]);
}
}
AcWing 796. 子矩阵的和