zoukankan      html  css  js  c++  java
  • 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;
    }
    
    
  • 相关阅读:
    Python实现简单中文词频统计示例
    Python组合类型笔记
    Python中turtle绘图学习笔记和实例
    Python爬虫入门
    与Python的第一次见面
    Delphi开发人员指南 第一部份快速开发的基础 第1章 Delphi下的Windows编程(四)
    Delphi开发人员指南 第一部份快速开发的基础 第1章 Delphi下的Windows编程(三)
    Delphi开发人员指南 第一部份快速开发的基础 第1章 Delphi下的Windows编程(二)
    Delphi开发人员指南 第一部份快速开发的基础 第1章 Delphi下的Windows编程(一)
    Java开发环境安装 配置 与 Eclipse安装 新建Project
  • 原文地址:https://www.cnblogs.com/WindZR/p/15363331.html
Copyright © 2011-2022 走看看