第三次做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; }
用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; }
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; }