第三次做cf,以后继续加油
A:
模拟,计算出0的左右两侧的个数和值,然后比较两侧个数的大小即可
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
#define MAX 100005
#define MOD 1e7
int ans[MAX*4];
long long l[MAX+5];
long long c[MAX+5];
int main(void)
{
int n;cin >> n;
for(int i = 1;i<=n;i++){
int loc = 0,v = 0;
scanf("%d%d",&loc,&v);
ans[loc+MAX]=v;
}
int a = 0,b = 0;
int s = 0,t = 0;
long long sum = 0;
for(int i = 0; i <= MAX*2;i++){
if(ans[i]){
if(i < MAX)a++,s+=ans[i],l[a]=s;
else if(i > MAX)b++,t+=ans[i],c[b]=t;
if(i == MAX) sum += ans[i];
}
}
int m;
m = min(a,b);
if(a>m)sum+=l[a]-l[a-m-1];
else sum+=l[a]-l[a-m];
if(b>m)sum+=c[m+1];
else sum+=c[m];
cout << sum;
}
B:
用hash统计数列中每个数的个数,记录开始和末尾的位置,同时得出最大的个数
然后在个数为最大个数的数字中找数列最小的子数列
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
#define MAX 1000005
#define MOD 1e7
int ans[MAX];
int loc[MAX][2];
int main(void)
{
int cnt = 0;
int n;cin >> n;
for(int i = 1;i<=n;i++){
int t;scanf("%d",&t);
if(!ans[t])loc[t][0]=i,loc[t][1]=i;
else loc[t][1]=i;
ans[t]++;
cnt = max(cnt,ans[t]);
}
int a=0,b=MAX;
for(int i=1;i<=MAX-1;i++){
if(ans[i]==cnt){
if(b-a>loc[i][1]-loc[i][0])a = loc[i][0],b = loc[i][1];
}
}
cout << a << ' ' << b;
}
C:
n个数变成相同的数,*2和/2两种操作,最少的操作次数是多少?
*2和/2很容易想到要将数字转化为二进制
然后先找最高位相同的部分
如1010 ,10,100,101
相同的部分就是10
剩下的位置要么为0,要么为-1(不存在)
所以对于后面不相同的部分,从第一次出现1,之后的所有数字包括1全部都要变成-1
这样处理后就剩下0,-1了然后就是
找保留至第多少列时的sum最小
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
#define MAX 100005
int ans[MAX][35];
int mp[MAX][35];
int c[MAX],col[35];
int main(void){
int n;cin >> n;
int cnt = 0,sum = 0;
memset(ans,-1,sizeof ans);
for(int i = 1;i<=n;i++){
int a;cin >> a;
int t=a,p = 1;
while(t){
mp[i][p]=t%2;t/=2;
p++;
sum++;
}
c[i]=p-1;
cnt = max(cnt,p-1);
int q = 1;
for(int j = p-1;j>=1;j--){
ans[i][q]=mp[i][j],q++;
}
}
int s = 0,v = 0;
for(int i = 1;i <= cnt;i++){
int p = 1;
for(int j = 1;j<n;j++){
if(ans[j][i]==ans[j+1][i])p++;
}
if(p==n)s = i;
else break;
}
for(int i = 1;i<=n;i++){
int flag = 0;
for(int j = s+1;j<=cnt;j++){
if(flag == 1)ans[i][j]=-1;
if(ans[i][j]==1){
v+=c[i]-j+1;
c[i]=j-1;
flag = 1;
ans[i][j]=-1;
}
}
}
int nmin = 10000000;
for(int i = s+1;i <= cnt;i++){
for(int j = 1;j <= n;j++)
if(ans[j][i]==0)col[i]++;
col[i]+=col[i-1];
}
for(int i = s;i <=cnt;i++)nmin=min(nmin,v+(i-s)*n-(col[i]-col[s])+(col[cnt]-col[i]));
cout << nmin;
}