#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int n;
long long a[1666666],f[1999999],s[1999999],t,w,sum;
int main(){
freopen("stick.in","r",stdin);
freopen("stick.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]),s[a[i]]++;//记录多少个
sort(a+1,a+n+1);
for(int i=n;i>=1;i--)
if(s[a[i]]%2==1){
if(s[a[i]]==1&&f[a[i]]==1) break;
s[a[i]]--,s[a[i]-1]++,a[i]--,f[a[i]]=1;}//削奇数个
sort(a+1,a+n+1);w=1;
for(int i=n;i>=1;i--){
if(s[a[i]]>=8)
sum+=(s[a[i]]/4-1)*a[i]*a[i],s[a[i]]=s[a[i]]%4+4;//四个的组成正方形
while(s[a[i]]>=2){
t++;
if(t%2==0) sum+=a[i]*a[w];
else w=i;
s[a[i]]-=2;} } //长方形
printf("%lld",sum);
}
思路:
这个题用枚举得了60
然后写了个n^2的过了,可能是相同的数很少吧
枚举约数,从中间向两边扩展,找到最大的区间
第二次再搜一次记下最大的区间
#include<cstdio>
#include<iostream>
using namespace std;
int n, a[366666],f[399999],p[399999],tot=0,max1=-8;
int main(){
freopen("select.in","r",stdin);
freopen("select.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
{
int l=i-1,r=i+1;
while(a[l]%a[i]==0&&a[l]>=a[i])l--;
while(a[r]%a[i]==0&&a[r]>=a[i])r++;
r--,l++;
max1=max(max1,r-l+1);
}
for(int i=1;i<=n;i++)
{
int l=i-1,r=i+1;
while(a[l]%a[i]==0&&a[l]>=a[i])l--;
while(a[r]%a[i]==0&&a[r]>=a[i])r++;
r--,l++;
if(r-l+1==max1&&!f[l]) tot++,p[tot]=l,f[l]=1;
}
printf("%d %d\n",tot,max1);
for(int i=1;i<=tot;i++)
printf("%d ",p[i]);
}
思路:
这道题写了个爆搜,竟过了九个点。。。。。。
正解zhw写的看着费心,就没看。。。
把爆搜贴出来吧。。
#include<cstdio>
#include<map>
using namespace std;
int f[1999999]; int tot;int p,l,r;
void dfs(int x,int a,int b)
{
if(x>p||a*b>r||b+1>r)return ;//少了这句话就30
dfs(x+1,a,b+1);
if(!f[a*b])
{
f[a*b]=1;
}
if(b!=0)
dfs(x+1,a*b,b);
}
int main(){
freopen("number.in","r",stdin);
freopen("number.out","w",stdout);
scanf("%d%d%d",&l,&r,&p);
f[1]=1;
dfs(1,1,0);
for(int i=l;i<=r;i++)
{
if(f[i])
tot++;
}
printf("%d",tot);
}