您的位置:首页 > 其它

Atcoder Grand Contest 19 题解

2017-08-27 15:51 423 查看
入坑atcoder,之前打过几场但是都是什么beginner test,,水的一匹。

tourist出的题目,害怕,向老大哥低头。

A

比较简单的水题。。贪心判就好了,反正四个东西是可以互相转化的。

#include<cstdio>
#include<algorithm>
#include<cstring>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int N=1e5+5;
typedef long long ll;
ll n;
ll a[5],b[5];
int main()
{
scanf("%lld%lld%lld%lld",&b[1],&b[2],&b[3],&b[4]);
scanf("%lld",&n);
a[1]=1,a[2]=2,a[3]=4,a[4]=8;
n*=4;
ll ans=0;
while (n>0)
{
ll m=0,s=0;
fd(i,4,1)
if (n>=a[i])
{
m=n%a[i];
s=n/a[i];
n=m;
ll tmp=s*b[i],j=i;
while (j>1)tmp=min(tmp,(s*=2)*b[j-1]),j--;
ans+=tmp;
}
}
printf("%lld\n",ans);
}


B

也挺水,但是卡了一会儿,菜的一匹。

根据题目要求,i<=j,可以发现i=j没卵用去掉。

然后剩余的,我就脑抽了,求不合法方案数很明显,问题是我居然一开始想的是回文串(智障),搞了半天manacher,最后发现只要端点不同就会GG,所以是个n^2水题。

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int N=3e5+5;
typedef long long ll;
char s
,s1
;
int vis[28];
int n,m;
ll ans;
int f
;
int main()
{
scanf("%s",s+1);
n=strlen(s+1);
fo(i,1,n)
{
vis[s[i]-'a'+1]++;
}
fo(i,1,n)
{
int c=s[i]-'a'+1;
vis[c]--;
ans+=i-1-(vis[c]);
}
printf("%lld\n",ans+1);
}


C

第一眼看题觉得是个水题,特殊点处理一下就好。

然后看见数据范围觉得很一颗赛艇。。x,y<=1e8不可能bfs

n<=2e5不可能spfa,哇有鬼。。

然后想是不是应该把点全部转化成左下右上然后跑个最短路,点数还是会超。

然后我硬是没想到lis。。

把所有点从左下到右上搞一下,然后求个lis。

正确性显然了,我要让经过的特殊点最多,横纵坐标又要递增(非严格),所以lis很符合。。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define Pi acos(-1.0)
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int N=3e5+5;
int n,m;
struct node
{
int x,y;
}a
;
int cnt,q
,len;
double ans;
bool flag;
bool cmp(node a,node b)
{
return a.x<b.x;
}
int main()
{
int x1,y1,y2,x2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
if (x2<x1)swap(x1,x2),swap(y1,y2);
if (y1>y2)y1=-y1,y2=-y2,flag=1;
scanf("%d",&n);
fo(i,1,n)
{
int x,y;
scanf("%d%d",&x,&y);
if (flag)y=-y;
if (x>=x1&&x<=x2&&y>=y1&&y<=y2)a[++cnt]=(node){x,y};
}
sort(a+1,a+1+cnt,cmp);
fo(i,1,cnt)
{
int l=1,r=len,ans=0;
while (l<=r)
{
int mid=(l+r)>>1;
if (a[i].y>q[mid])l=mid+1,ans=mid;
else r=mid-1;
}
if (ans==len)q[++len]=a[i].y;
else q[ans+1]=min(q[ans+1],a[i].y);
}
ans=(x2-x1+y2-y1)*100.0;
if (x1==x2||y1==y2)
{
if (cnt)ans+=10.0*Pi-20.0;
}
else
{
ans-=(20-5.0*Pi)*len;
if (len==min(x2-x1,y2-y1)+1)ans+=5*Pi;
}
printf("%.13lf\n",ans);
return 0;
}


D

stl题(???)

反正看见A的人STL用到飞起,让我这个没用过vector的心情复杂。。

具体的话应该是枚举偏移量?然后直接暴力求贡献。。感觉像是那种贪心模拟,但是细节鬼畜。

时间复杂度n^2log。

#include <bits/stdc++.h>

using namespace std;

const int N = 2017;

char a
, b
;
char x
;
pair<int, int > ve
;

int main() {
scanf("%s", a);
scanf("%s", b);
int n = strlen(a);
int ans = 1e8;
for (int sl = -n; sl <= n; sl++) {
int cnt = 0;
for (int i = 0; i < n; i++) {
x[i] = a[(i+n-sl) % n];
cnt += x[i] != b[i];
ve[i] = make_pair(-1e8, 1e8);
}
if (cnt == 0)
ans = min(ans, abs(sl));
int last = -1;
for (int i = 0; i < 3 * n; i++) {
if (b[i % n] == '1')
last = i;
if (x[i % n] != b[i % n]) {
if (last == -1) continue;
ve[i % n].first = max(min(last - i + sl, 0), ve[i % n].first);
}
}

last = -1;
for (int i = 3 * n; i >= 0; i--) {
if (b[i % n] == '1')
last = i;
if (x[i % n] != b[i % n]) {
if (last == -1) continue;
ve[i % n].second = min(max(last - i + sl, 0), ve[i % n].second);
}
}
vector<pair<int, int > > vv;
for (int i = 0; i < n; i++) if (b[i] != x[i])
vv.push_back(ve[i]);
sort(vv.begin(), vv.end());
int ri = max(0, sl);
for (int le = -n, j = 0; le <= min(sl, 0); le++) {
while (j < vv.size() && vv[j].first < le) ri = max(ri, vv[j].second), j++;
ans = min(ans, cnt + ri-le + ri - le -abs(sl));
}
}
if (ans >= 1e8)
ans = -1;
printf("%d\n", ans);
return 0;
}


E,F待填坑~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: