[原创]Codeforces Round #421 (Div. 2)
2017-06-28 03:17:32 Tabris_ 阅读数:539
博客爬取于2020-06-14 22:39:52
以下为正文
版权声明:本文为Tabris原创文章,未经博主允许不得私自转载。
https://blog.csdn.net/qq_33184171/article/details/73825637
第一次完全凭自己水平进了d2 前50(最后居然变成了36…hhh), 然后因为我没做的C题数据出锅而unrated…
不开心啊…
————————————————————————————————————————————
日常简单模拟题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| int main(){ int c,v0,v1,a,l; scanf("%d%d%d%d%d",&c,&v0,&v1,&a,&l);
int p=0,ans=0,flag=0; while(p<c){ ans++; if(flag) p-=l; flag=1; p+=v0; v0+=a; v0=min(v0,v1); }
printf("%d\n",ans); return 0; }
|
————————————————————————————————————————————
给你一个正n变形,和一个角度a
让你找三个点,使得这三个点构成的角,与a相减的绝对值最小
首先我们可以知道多边形的顶点是共圆的,所以以一个点为顶点的时候,其他边的圆周角大小相等,所以固定两个点也就是一个边,枚举另一个点即可
由于数据范围小,O(n) 维护即可,如果大了点的话 需要三分求解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| int n; double a; int main(){ scanf("%d",&n); scanf("%lf",&a); double b=(n-2)*180/n,mi=411; int ans = 1; for(int i=1;i<=n-2;i++){ if(abs(180.0/n*i-a)<mi){ mi=abs(180.0/n*i-a); ans=i; } }
printf("%d %d %d\n",n,n-1,ans); return 0;
}
|
————————————————————————————————————————————
题目问题比较大啊 正解最后都没有明确。 不补了
————————————————————————————————————————————
给你一个长度为n的序列
可以旋转n次,
问你$$\sum_{i=1}^n\Big|p[i]-i \Big|$$的值最小的时候是多少 需要旋转几次
k=0:shift p1,p2,...pn,k=1:shift pn,p1,...pn−1,...,k=n−1:shift p2,p3,...pn,p−1.
其实很简单,
我们可以观察到每次旋转,除了最后一个数之外,其他的数需要减去的值都+1了
那么就是p[i]−i为非正值得数贡献+1,正数的数贡献坚毅
p[i]−i相当于变成p[i]−(i+1) ,那也就是(p[i]−1)−i
那么我们可以先算出初始的∑i=1np[i]−i结果,然后每次按照上述规则计算即可,
方法是用一个数组h[j]记录p[i]−i为j的数有多少个
对于p[i]−1的情况 其实就用一个变量维护一个零线 就可以了
处理下前缀和即可,
由于序列最后一个值要特殊处理,所有会有修改,所以采用BIT进行维护
在每次旋转中维护答案即可
总复杂度:O(nlogn)
--------Update------
刚才又想了想 发现这个过程根本不需要BIT,直接数组,零线外加两个变量就行了,是能做到O(1)的。
附本题代码
————————————————————————————————————
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| # include <bits/stdc++.h>
using namespace std; typedef long long int LL;
# define abs(x) ((x)>0?(x):-(x))
const int N = 2e6+10;
/******************************************************/
int z[N],f[N],p[N],n;
int sum[N*4]; # define lowbit(x) (x&-x) void update(int i,int v){for(;i<n*4;i+=lowbit(i)) sum[i]+=v;} int getsum(int i){int ans=0; for(;i;i-=lowbit(i)) ans+=sum[i]; return ans;}
int main(){ memset(sum,0,sizeof(sum)); scanf("%d",&n); LL tmp=0,tem=0;int ans = 0,dd=n; for(int i=1;i<=n;i++){ scanf("%d",&p[i]); tmp+=abs(p[i]-i); update(p[i]-i+n,1); }
tem=tmp; for(int i=2;i<=n;i++){ tem-=abs(p[n-i+2]-n); tem+=abs(p[n-i+2]-1);
update(p[n-i+2]-(n-i+2)+n,-1);
int t=getsum(dd); tem+=t; tem-=n-1-t;
dd++; update(p[n-i+2]-1+dd,1);
if(tem<tmp){ tmp=tem; ans=i-1; } }
printf("%lld %d\n",tmp,ans); return 0; }
|
————————————————————————————————————————————