noip模拟66
Posted WindZR
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了noip模拟66相关的知识,希望对你有一定的参考价值。
考试过程:可能受到了自己生病的一些影响,这次考试状态不是很好。做题的时候比较困。我按顺序开题,首先是T1,这题挺有意思,显然是一道DP题,但是刚开始我想的是类似于\\(f_{i,j}\\)表示第1个序列选\\(i\\)个,第二个序列选\\(j\\)个的最大值,但是这么转移不仅复杂度很高并且转移也很麻烦。我又想了想觉得可以将两个序列分开考虑,最后再合并,反正只要体积是一定的就是对的,然后就切了。
T2,这题考场上实在没什么思路,就打了个暴搜。T3,我觉得部分分挺多,但是我读错题了,导致我获得了\\(0pts\\)的高分...。总之,以后还是要多注意身体,生病啥的都会影响考试状态。
T1 接力比赛
思路:上面说的差不多了,我将左右两边分开考虑,我的朴素DP是\\(f_{i,j}\\)表示第一个序列以\\(i\\)结尾的总体积为\\(j\\)的最大值,\\(g_{i,j}\\)同理,那么转移是显然的\\(f_{i,j}=max(f_{i,j},f_{k,j-w_i}+v_i)\\),这样的复杂度是\\(n^2\\times U\\)的,复杂度比较高,然后我观察这个DP式子,发现这好像是一个背包,然后我就按照背包DP的思路优化了一下\\(f_{i,j}=max(f_{i-1,j},f{i-1,j-w_i}+v_i)\\),这样就把复杂度降掉一个\\(n\\),然后卡卡上界这道题就切了。
代码如下:
AC_code
#include<bits/stdc++.h>
#define int long long
#define re register int
#define ii inline int
#define iv inline void
#define f() cout<<"fuck"<<endl
using namespace std;
const int N=1e6+10;
const int M=1010;
const int INF=1e18;
int n,m,ans;
int f[N],g[N],s1[N],s2[N];
struct node
{
int w,v;
}c1[M],c2[M];
ii read()
{
int x=0;char ch=getchar();bool f=1;
while(ch<\'0\' or ch>\'9\')
{
if(ch==\'-\') f=0;
ch=getchar();
}
while(ch>=\'0\' and ch<=\'9\')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return f?x:(-x);
}
signed main()
{
freopen("game.in","r",stdin),freopen("game.out","w",stdout);
n=read(),m=read();
for(re i=1;i<=n;i++) c1[i]=(node){read(),read()},s1[i]=s1[i-1]+c1[i].w;
for(re i=1;i<=m;i++) c2[i]=(node){read(),read()},s2[i]=s2[i-1]+c2[i].w;
int up=max(s1[n],s2[m]);
for(re i=1;i<=up;i++) f[i]=g[i]=-INF;
f[c1[1].w]=c1[1].v;
for(re i=2;i<=n;i++)
for(re p=s1[i];p>=c1[i].w;p--)
f[p]=max(f[p],f[p-c1[i].w]+c1[i].v);
g[c2[1].w]=c2[1].v;
for(re i=2;i<=m;i++)
for(re p=s2[i];p>=c2[i].w;p--)
g[p]=max(g[p],g[p-c2[i].w]+c2[i].v);
for(re i=1;i<=up;i++) ans=max(ans,f[i]+g[i]);
printf("%lld\\n",ans);
return 0;
}
T2 树上竞技
留坑
T3 虚构推理
思路:我在考场上看错题了,这道题其实是将时针与时针的夹角比较,分针和分针的夹角比较,然后取个\\(max\\),但是我直接把当前时间点的角度进行了比较。知道了题意,那我们考虑做法,首先我们可以枚举\\(i,j,k\\)表示时,分,秒。然后计算取最小的最大值即可。
计算的话利用一个\\(upper_bound\\)将排序后的数组二分查找即可。
注意1.我们要将边界设为\\(a_0=a_n,a_{n+1}=a_1\\),这样可以避免很多问题。
2.在计算角度的时候我们利用了\\(t2=t1+180\\),但是要计算夹角我们要用\\(180-t2-a_p\\),不能直接用\\(t1-a_p\\),因为这样算出来的夹角可能是钝角。
代码如下:
AC_code
#include<bits/stdc++.h>
#define re register int
#define ii inline int
#define iv inline void
#define f() cout<<"fuck"<<endl
#define head heeadd
#define next net
#define D double
using namespace std;
const int N=5e4+10;
const double eps=1e-6;
int n;
double ans=999999999.999999;
int h[N],m[N],s[N];
double du[N],dh[N],dm[N];
char ch[N];
ii read()
{
int x=0;char ch=getchar();bool f=1;
while(ch<\'0\' or ch>\'9\')
{
if(ch==\'-\') f=0;
ch=getchar();
}
while(ch>=\'0\' and ch<=\'9\')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return f?x:(-x);
}
signed main()
{
freopen("unreal.in","r",stdin),freopen("unreal.out","w",stdout);
n=read();
for(re i=1;i<=n;i++)
{
scanf("%s",ch+1);
int len=strlen(ch+1),tmp=0,flag=0;
for(re j=1;j<=len;j++)
{
if(ch[j]==\':\')
{
if(flag==0) h[i]=tmp;
else if(flag==1) m[i]=tmp;
++flag,tmp=0;
continue;
}
tmp=tmp*10+ch[j]-\'0\';
}
s[i]=tmp;
if(h[i]>=12) h[i]=h[i]%12;
dh[i]=(double)h[i]*30.00000+(double)m[i]*0.50000+(double)s[i]*0.5/60.0;
dm[i]=(double)m[i]*6.00000+(double)s[i]*0.10000;
}
sort(dh+1,dh+n+1),sort(dm+1,dm+n+1);
dh[0]=dh[n],dh[n+1]=dh[1];
dm[0]=dm[n],dm[n+1]=dm[1];
for(re i=0;i<12;i++)
{
for(re j=0;j<60;j++)
{
for(double k=0.00000;k<60;k+=0.01)
{
double maxx=0.000,t1,t2;
int pos;
t1=(double)i*30.0000+(double)j*0.50000+k*0.5/60.0;
t2=t1+180.00;
if(t2>=360) t2-=360.00;
pos=upper_bound(dh+1,dh+n+1,t2)-dh;
double tmp1=180-(dh[pos]-t2);
double tmp2=180-(t2-dh[pos-1]);
if(tmp1>=360) tmp1-=360;if(tmp1<0) tmp1+=360;
if(tmp2>=360) tmp2-=360;if(tmp2<0) tmp2+=360;
t1=(double)j*6.00+k*0.10;
t2=t1+180.00;
if(t2>=360) t2-=360.00;
pos=upper_bound(dm+1,dm+n+1,t2)-dm;
double tmp3=180-(dm[pos]-t2);
double tmp4=180-(t2-dm[pos-1]);
if(tmp3>=360) tmp3-=360;if(tmp3<0) tmp3+=360;
if(tmp4>=360) tmp4-=360;if(tmp4<0) tmp4+=360;
tmp1=min(tmp1,360-tmp1);
tmp2=min(tmp2,360-tmp2);
tmp3=min(tmp3,360-tmp3);
tmp4=min(tmp4,360-tmp4);
maxx=max(max(tmp1,tmp2),max(tmp3,tmp4));
ans=min(ans,maxx);
}
}
}
printf("%.6lf\\n",ans);
return 0;
}
以上是关于noip模拟66的主要内容,如果未能解决你的问题,请参考以下文章