zoukankan      html  css  js  c++  java
  • AtCoder ABC 163 题解(难题日常咕咕咕

    第一场 AtCoder 比赛,结果你告诉我是 unrated?
    看来只能做人均会的题了。
    总分:(100+200+300+400+0(AC×5)+0=1000)
    写一下简要题解:
    按我 (A) 题顺序来。
    (网太卡了,把题全打开,谁先加载出来先搞谁

    (C).

    给一棵以 (1) 为根的树,并给出其它点的父亲,求每个点有几个儿子。
    直接开个数组记录就好了:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<stack>
    #include<queue>
    using namespace std;
    
    #define read(x) scanf("%d",&x)
    #define readl(x) scanf("%lld",&x)
    #define ll long long 
    #define ull unsigned long long
    
    int n,l;
    int b[200005]={0};
    
    int main()
    {
    	read(n);
    	for(int i=2;i<=n;i++) read(l),b[l]++;
    	for(int i=1;i<=n;i++) printf("%d
    ",b[i]);
    	return 0;
    } 
    
    

    然后 (CE) 只因选错语言,还 (CE) 了两次,罚时 (10;min) 亏死了。

    (A).

    给出圆的半径,求圆的直径。

    [C=2pi r ]

    依稀记得 (FFT)(pi=acos(-1)),直接算就行了。
    不卡精度真是太好了。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<stack>
    #include<queue>
    using namespace std;
    
    #define read(x) scanf("%d",&x)
    #define readl(x) scanf("%lld",&x)
    #define ll long long 
    #define ull unsigned long long
    
    double pi=acos(-1.0);
    double n; 
    
    int main()
    {
    	cin>>n;
    	printf("%.20lf
    ",2*n*pi); 
    	return 0;
    } 
    
    

    (B).

    有一些工作需要的时间和拥有来办公的总时间,求做完工作后剩多少时间,若做不完,输出 (-1)
    前缀和,注意long long

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<stack>
    #include<queue>
    using namespace std;
    
    #define read(x) scanf("%d",&x)
    #define readl(x) scanf("%lld",&x)
    #define ll long long 
    #define ull unsigned long long
    
    int n,m;
    int b[10005];
    ll sum=0;
    
    int main()
    {
    	read(n),read(m);
    	for(int i=1;i<=m;i++) read(b[i]),sum+=b[i];
    	if(sum>n) printf("%d
    ",-1);
    	else printf("%d
    ",n-sum);
    	return 0;
    } 
    

    (D)

    (10^{100},10^{100}+1......10^{100}+N) 中选 (k)(N+1) 个数,求可以得到值数的和。
    稍有思维难度,但还是一眼题。
    发现得到的数都是连续的,直接求最大值和最小值相减即可,选不同个的最值显然是可以前、后缀和优化递推的。
    复杂度 (mathcal O(n))

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<stack>
    #include<queue>
    using namespace std;
    
    #define read(x) scanf("%d",&x)
    #define readl(x) scanf("%lld",&x)
    #define ll long long 
    #define ull unsigned long long
    #define MOD 1000000007
    
    int n,m;
    ll q[200005],h[200005];
    ll sum=0;
    
    int main()
    {
    	read(n),read(m);
    	q[0]=0,h[n+1]=0;
    	for(int i=1;i<=n;i++) q[i]=q[i-1]+1ll*i;
    	for(int i=n;i>=1;i--) h[i]=h[i+1]+1ll*i;
    	for(int i=m;i<=n;i++) sum=(sum+h[n-i+1]-q[i-1]+1)%MOD;
    	printf("%lld
    ",(sum+1)%MOD);
    	return 0;
    } 
    

    (E).

    (n) 个人,每个人有一个价值 (c_i) ,把他们打乱,假设从前的位置是 (a_i),现在的位置是 (b_i),最大化 (sumlimits_{i=1}^nc_i|a_i-b_i|)
    贪心,优先放置 (c) 小的人。
    为什么呢?

    由于我们在记录状态时无法大范围看全局,先选择影响小的人。
    我们设 (dp_{i,j}) 为选 (j-i+1)个人放在 (i)(j) 的区间上的最大贡献。
    我们以此为基础扩大区间,即判断先一个应该放左边还是右边。

    这里转移方程易得为:

    [dp_{i,j}=max{max(dp_{i+1,j}+c_{j-i+1}|a_{j-i+1}-l|,dp_{i,j-1}+c_{j-i+1}|a_{j-i+1}-r|)} ]

    (Code):

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    
    #define ll long long 
    #define read(x) scanf("%d",&x)
    
    struct node
    {
    	int id,val;
    }a[2005];
    ll dp[2005][2005];
    int n;
    
    bool cmp(node n,node m){return n.val<m.val;}
    
    int main()
    {
    	read(n);
    	for(int i=1;i<=n;i++) read(a[i].val),a[i].id=i;
    	sort(a+1,a+n+1,cmp);
    	for(int i=1;i<=n;i++) dp[i][i]=1ll*a[1].val*abs(a[1].id-i);
    	for(int i=2;i<=n;i++)
    	{
    		for(int l=1;l+i-1<=n;l++)
    		{
    			int r=l+i-1;
    			dp[l][r]=0;
    			dp[l][r]=max(dp[l][r],max(dp[l+1][r]+1ll*a[i].val*abs(a[i].id-l),dp[l][r-1]+1ll*a[i].val*abs(a[i].id-r)));
    		}
    	}
    	printf("%lld
    ",dp[1][n]);
    }
    

    (F).

    咕咕咕......
    最后得了 (1000;pts+39.10;min;;;rk1654)
    太菜了,没人权, (dp) 功夫需要继续加强。
    要是没有选错语言就能 (rk1081) 了。(然而没有切出 (E) 题才是原罪。

  • 相关阅读:
    DotNet 获取所有 SQL Server 的数据库实例名称
    SQL Server 2008 R2 导出数据脚本的方法
    使用 Jquery 获取 Internet Explorer 浏览器版本
    OpenCV(EmguCV)2.1新特性介绍之图像差异StereoSGBM与设置窗口属性SetWindowProperty(StereoSGBM Of OpenCV 2.1)
    OpenCV(EmguCV)2.1新特性介绍之图像分割GrabCut(GrabCut Of OpenCV 2.1)
    背景建模与前景检测之三(Background Generation And Foreground Detection Phase 3)
    使用Lingobit Localizer汉化.net程序(Translate .net program using Lingobit Localizer)
    返修&售后服务管理网站设计与源码
    解决Windows7无法安装SP1补丁包及无法显示Windows功能列表的方法
    javascript获取到textarea文本框中的回车换行符
  • 原文地址:https://www.cnblogs.com/tlx-blog/p/12741356.html
Copyright © 2011-2022 走看看