A.
记录一下前缀和,二分找一下超过一半的地方就行了。
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int n,i,j,sum[200005]={0};
cin>>n;
for(i=1;i<=n;i++){
scanf("%d",&j);
sum[i]+=sum[i-1]+j;
}
int half=sum[n]/2;if(sum[n]&1)half++;
int len=lower_bound(sum+1,sum+1+n,half)-sum;
cout<<len<<endl;
return 0;
}
B.
注意细节即可;
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#include<string>
using namespace std;
int main()
{
int n,a,b,i,j,k;
cin>>n>>a>>b;string str;cin>>str;
priority_queue<int>que;//存放所有空闲位置的长度
for(i=0;i<str.size();i++){
if(i<str.size()&&str[i]=='.'){
int cnt=0;
while(i<str.size()&&str[i]=='.'){
cnt++;i++;
}
que.push(cnt);
}
}
int cnt=0;
while(que.size()&&que.top()!=1){//在空闲位置长度大于1之前都要考虑不相邻问题
int t=que.top();que.pop();
if(a==0&&b==0)break;
if(a-t/2>=0)a-=t/2,cnt+=t/2;
else cnt+=a,a=0;
if(b-t/2>=0)b-=t/2,cnt+=t/2;
else cnt+=b,b=0;
if(t&1){
if(a>=b&&a)a-=1,cnt+=1;
else if(b)b-=1,cnt+=1;
}
}
int total=0;
if(que.size()&&(a+b)){//如果还有长度为1的位置,并且人也没放完
while(!que.empty()){
total+=que.top();que.pop();
}
}
cnt+=min(a+b,total);
cout<<cnt<<endl;
return 0;
}
C.
数据不大,最多2e9,所以直接枚举每一位要不要删去即可,最多也就2^9种,用一个二进制数来记录删去的位。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<map>
#include<algorithm>
#include<vector>
using namespace std;
int main()
{
int n,i,j,k;
cin>>n;int m=n;i=0;map<int,int>ys;
while(m){
j=m%10;ys[1<<i]=j;
m/=10;i++;
}
int cnt=i;
int maxwei=(1<<i)-1;int minn=0x7f7f7f7f;
for(i=1;i<=maxwei;i++){
j=i;int num=0;bool iszero=false;
vector<int>temp;
while(j){
k=j&-j;j-=k;
temp.push_back(ys[k]);
if(!ys[k])iszero=true;
else if(ys[k]&&iszero)iszero=false;
}
if(iszero)continue;
else{
reverse(temp.begin(),temp.end());
for(auto i=temp.begin();i!=temp.end();i++)
num=num*10+*i;
int w=sqrt(num);
if(w*w==num){
j=i;int cnt1=0;
while(j){
j-=j&-j;cnt1++;
}
minn=min(minn,cnt-cnt1);
}
}
}
if(minn<0x7f7f7f7f)
cout<<minn<<endl;
else cout<<-1<<endl;
return 0;
}
D.
我们使用一个map来记录每个数值出现的位置,那么如果任何一个数值出现了第二次,它一定会与第一次出现的位置上的数发生合并。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
typedef long long ll;
map<ll,int>pos;//第一个键值是数值,第二个是数值出现的位置
ll a[150005];//用于存读取的数
int main()
{
int n,i,j;
cin>>n;int ans=n;
for(i=1;i<=n;i++){
scanf("%lld",&a[i]);
while (pos[a[i]]!=0){//如果这个数值出现过了
a[pos[a[i]]]=0;//第一次出现的位置清楚
ans--;
pos[a[i]]=0;//当前位置清除,因为很可能合并之后的数值又是出现过的
a[i]*=2;
}
pos[a[i]]=i;
}
cout<<ans<<endl;
for(i=1;i<=n;i++)
if(a[i])
printf("%lld%c",a[i],i==n?'\n':' ');
return 0;
}