A:正反跑一遍就能求出最长不同数距离
#include<bits/stdc++.h>
using namespace std;
const int M =300000+100;
int a[M];
int dis[M];
int vis[M];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
int ma=0;
for(int i=1;i<=n;i++)
{
if(a[i]!=a[n])
{
ma=max(ma,n-i);
break;
}
}
for(int i=n;i>=1;i--)
{
if(a[i]!=a[1])
{
ma=max(ma,i-1);
break;
}
}
printf("%d\n",ma);
return 0;
}
B:
枚举前k个,判断前k个能否放进冰箱里。
最大的肯定单放,然后次大的于最大的放一层,次次大的单放…………以此类推
#include<bits/stdc++.h>
using namespace std;
const int M =100000+100;
int aa[M];
int a[M];
int b[M];
int h;
bool check(int n)
{
for(int i=1;i<=n;i++)
a[i]=aa[i];
int b1=0;
sort(a+1,a+1+n);
int cnt=0,now=0,nowv=0;
for(int i=n;i>=1;i--)
{
if(now<cnt)
{
now++;
continue;
}
b1+=a[i];
if(b1>h)
{
now++;
// printf("%d %d cnt=%d\n",now,a[i],cnt);
if(cnt<now)
{
return false;
}
b1-=a[i];
}
else
{
b[++cnt]=a[i];
}
}
return true;
}
int main()
{
int nn;
cin>>nn>>h;
int b1=0,b2=0;
for(int i=1;i<=nn;i++)
{
scanf("%d",&aa[i]);
}
int l=1,r=nn;
int pos=0;
for(int i=1;i<=r;i++)
{
if(!check(i))
{
printf("%d\n",i-1);
return 0;
}
}
/* while(l<=r)
{
int mid=(l+r)/2;
// printf("%d ------ %d\n",l,r);
if(check(mid))
{
l=mid+1;
pos=mid;
}
else
r=mid-1;
}*/
printf("%d\n",r);
return 0;
}
C:、行列都是偶数就行。
#include<bits/stdc++.h>
using namespace std;
const int M =500+100;
int a[M][M];
int b[M][M];
int c[M][M];
int vis[M];
int main()
{
int n,m;cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
scanf("%d",&b[i][j]);
if(a[i][j]!=b[i][j])c[i][j]=1;
// printf("%d",c[i][j]);
// if(j==m)
// puts("");
}
bool f=true;
int h=0,l=0;
for(int i=1;i<=m;i++)
{
l=0;
for(int j=1;j<=n;j++)
{
l+=c[j][i];
}
if(l%2==1)
{
f=false;
break;
}
}
for(int i=1;i<=n;i++)
{
l=0;
for(int j=1;j<=m;j++)
{
l+=c[i][j];
}
if(l%2==1)
{
f=false;
break;
}
}
if(f)
puts("Yes");
else
puts("No");
/*for(int i=1;i<=n;i++)
{
if(!vis[i])
{
vis[i]=1;
for(int j=i;j<=n;j++)
{
if(!vis[j])
{
vis[j]=1;
for(int k=1;k<=m;k++)
{
if(c[i][k]!=c[j][k])
}
}
}
}
}*/
return 0;
}
D;
根据样例解释的表,我们观察可以发现。
如果把s【i】进行排序,那每一行的权值(除了第一行)都是s[i]-s[i-1]于len的最小值
由此我们排序 去重,出去第一个 对2--》n的数进行查分处理,然后二分找到大于len的数,最后求解即可
#include<bits/stdc++.h>
using namespace std;
const int M = 100000+100;
long long a[M],s[M],c[M];
int main()
{
int n;
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n;
for(int i=1;i<=n;i++)
cin>>s[i];
sort(s+1,s+1+n);
n=unique(s+1,s+1+n)-(s+1);
for(int i=1;i<n;i++)
c[i]=s[i+1]-s[i];
sort(c+1,c+n);
for(int i=1;i<n;i++)
a[i]=c[i]+a[i-1];
long long q,l,r;
cin>>q;
for(int i=1;i<=q;i++)
{
cin>>l>>r;
long long len=(r-l+1);
long long ff=lower_bound(c+1,c+n,len)-c;
// cout<<endl<<ff<<"---ff"<<endl;
// cout<<a[ff-1]<<"----a[ff-1]"<<endl;
if(i==1)
cout<<a[ff-1]+len*(n-ff+1);
else
cout<<" "<<a[ff-1]+len*(n-ff+1);
}
cout<<endl;
return 0;
}
E先取3个 再取2大一小,不知道对不对明天交试试
E题我的处理比较好理解,可能代码多点。。
边读边处理,从最小的边开始,
要么是当前木棍选2个+一个之前剩的木棍,要么是三个当前木棍。很明显,最好是先利用完之前剩的木棍,再进行后面木棍的操作。
然后就是简单的模拟就行了。
#include<bits/stdc++.h>
using namespace std;
int n;
long long t,rest,sum;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n,x;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>x;
int w=x/2;
if(w>rest)//当前木棍选2个加上之前剩下的一个木棍的情况
{
x-=rest*2;
sum+=rest;
rest=x;
}
else
{
rest=rest-w+x%2;
sum+=w;
x=x%2;
}
if(x>=3)//选三个当前木棍
{
sum+=x/3;
rest=x%3;
}
// printf("rest=%d sum=%d i = %d x = %d\n",rest,sum,i,x);
}
cout<<sum<<endl;
return 0;
}
/*
*这种就是只考虑剩下的木棍,最后用总和减去剩下的木棍
*
*/
#include<cstdio>
using namespace std;
int n;
long long t,rst,sum;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&t);
sum+=t;
if(t>=2*rst) rst=(t-2*rst)%3;
else rst=rst-t/2+t%2;
}
printf("%lld",(sum-rst)/3);
}