Atcoder Grand Contest 19 题解

入坑atcoder,之前打过几场但是都是什么beginner test,,水的一匹。
tourist出的题目,害怕,向老大哥低头。

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

#include
#include
#include
#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
#include
#include
#include
#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[N],s1[N];
int vis[28];
int n,m;
ll ans;
int f[N];
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
#include
#include
#include
#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[N];
int cnt,q[N],len;
double ans;
bool flag;
bool cmp(node a,node b)
{
    return a.xx;
}
int main()
{
    int x1,y1,y2,x2;
    scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
    if (x2if (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 

using namespace std;

const int N = 2017;

char a[N], b[N];
char x[N];
pair<int, int > ve[N];

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);
      }
    }
    vectorint, 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待填坑~~

你可能感兴趣的:(Atcoder,比赛总结)