这场被精度坑成SB了,因为精度问题WA了C和E,C题加一个误差修正值就GG了...E题三分精度用次数控制,但是我写循环的时候还是while(l<=r)了...哎 好弱。
A 判断输入的数字转化为二进制有多少个1即可...
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
int n;
scanf("%d",&n);
int ans=0;
while(n)
{
int t=n%2;
ans+=t;
n=n/2;
}
printf("%d\n",ans);
return 0;
}
B 贪心,每次找最大的数字,并且这个数字所在的列和行都没被使用过..因为当时感觉B题不会出太难,果断贪心写了就对了..
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int dp[2000][2000];
int used[2000],ans[2000];
int main()
{
int n;
scanf("%d",&n);
memset(dp,0,sizeof(dp));
for(int i=2;i<=2*n;i++)
{
for(int j=1;j<=i-1;j++)
{
scanf("%d",&dp[i][j]);
dp[j][i]=dp[i][j];
}
}
memset(used,0,sizeof(used));
for(int i=0;i<n;i++)
{
int maxi=-1,ti=-1,tj=-1;
for(int j=1;j<=2*n;j++)
{
for(int k=1;k<=j-1;k++)
{
if(used[j]==0&&used[k]==0)
{
if(dp[j][k]>maxi)
{
maxi=dp[j][k];
ti=j;tj=k;
}
}
}
}
used[ti]=used[tj]=1;
ans[ti]=tj;
ans[tj]=ti;
}
for(int i=1;i<2*n;i++)
printf("%d ",ans[i]);
printf("%d\n",ans[n*2]);
return 0;
}
C ...乱搞的数学题...因为公式不是窝推导的,不说啥。.
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
int a,b;
scanf("%d %d",&a,&b);
if(a<b)
{
printf("-1\n");
return 0;
}
double sum=a+b+0.0;
double ans;
sum=sum/2.0;
ans=(int)(sum/b+0.0);//此处窝室友推荐加一个比较小的数字来修正,果断FST了,删除了这个修正值就过了,精度卡的真真日了狗
sum=sum/ans;
printf("%.10f\n",sum);
return 0;
}
预先处理出前缀或和,后缀或和,直接枚举 复杂度O(n)
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define MAXN 200010
ll l[MAXN],r[MAXN];
ll a[MAXN];
int main ()
{
int n,k,x;
scanf("%d %d %d",&n,&k,&x);
l[1]=r[n+1]=0;
for(int i=1;i<=n;i++)
{
scanf("%I64d",&a[i]);
l[i]=l[i-1]|a[i];
}
for(int i=n;i>=1;i--)
r[i]=r[i+1]|a[i];
ll ans=0;
for(int i=1;i<=n;i++)
{
ll tmp=a[i];
for(int j=1;j<=k;j++)
tmp*=x;
ans=max(ans,l[i-1]|r[i+1]|tmp);
}
printf("%I64d\n",ans);
return 0;
}
E. 给定一个n的序列,找出一个x,使得所有的序列中的数字-x后,这个序列的最大子段和最小,最大子段和是绝对值的,一段和是负数,要负数取绝对值计算在内...
因为x很大或者很小肯定子段和绝对值很大,在ansx这点左右两边扩大最大子段和都在增加,那么函数图像就是一个三分搜索的图像...直接三分,然后dp再O(n)的复杂度内求的最大子段和...这个题用次数控制三分精度比较好...
#include<bits/stdc++.h>
using namespace std;
#define eps 1e-7
#define ll long long
#define M 220000
int a[M],n;
double f[M],ans;
double cal(double x)
{
double ans1=0;
f[1]=a[1]-x;
for(int i=2;i<=n;i++)
{
if(f[i-1]<0)
f[i]=a[i]-x;
else
f[i]=f[i-1]+a[i]-x;
ans1=max(ans1,f[i]);
}
f[1]=(a[1]-x);
ans1=max(ans1,-f[1]);
for(int i=2;i<=n;i++)
{
if(f[i-1]>0)
f[i]=(a[i]-x);
else
f[i]=f[i-1]+(a[i]-x);
ans1=max(ans1,-f[i]);
}
return ans1;
}
void sf(double l,double r)
{
double mid,midmid;
int tmp=0;
while(1)
{
mid=(l+r)/2;
midmid=(mid+r)/2;
double x=cal(mid);
double y=cal(midmid);
if(x<y)
{
ans=min(ans,x);
r=midmid;
}
else
{
ans=min(ans,y);
l=mid;
}
tmp++;
if(tmp>500)
break;
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
ans=10000000000;
sf(-100000,10000);
printf("%.9f\n",ans);
return 0;
}