Loading

1020考试总结

T1

比较简单的判断题,考虑对于一个数\(x\)他最大可以从\((x+1)^2-1\)得到

#include <cstdio>
#include <iostream>
#include <string>

using namespace std;

string s;

int main()
{
  //freopen("sqrt.in","r",stdin);
  //freopen("sqrt.out","w",stdout);
  while(cin>>s)
  {
    bool flag=0;
    __int128 a=0,maxlonglong=(__int128)((__int128)(1)<<32)-1;
    for(int i=0;i<s.size();i++)
    {
      a=a*10+s[i]-'0';
      if(a>maxlonglong)
      {
        printf("TAT\n");
        flag=1;
        break;
      }
    }
    if(!flag)
    {
      if(a==0)
      {
        printf("TAT\n");
        continue;
      }
      __int128 now=1;
      int wc=1;
      while(now<a)
      {
        now=(__int128)((__int128)(1)<<((__int128)(1)<<wc))-1;
        wc++;
      }
      printf("%d\n",wc-1);
    }
  }
}

T2

不会,用非正解的保留边然后暴力跑kru过了

#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

struct Point
{
  long long x,y;
}p[2010];

struct Edge
{
  int a,b;
  long long v;
}e[4000010],ep[1000010];

struct Poly
{
  vector<int> vp;
  long long v;
}cpo[15];

int n,m,cnt,cnt2,edgecnt;

int f[2010],size[2010];

long long ans=0x3f3f3f3f3f3f3f3f;

int find(int x)
{
  if(f[x]==x) return x;
  return f[x]=find(f[x]);
}

bool merge(int x,int y)
{
  int fx=find(x),fy=find(y);
  if(fx==fy) return 0;
  edgecnt++;
  if(size[fx]>size[fy]) swap(fx,fy);
  f[fx]=fy;
  size[fy]+=size[fx];
  return 1;
}

void addedge(int a,int b,long long v)
{
  e[++cnt].a=a;
  e[cnt].b=b;
  e[cnt].v=v;
}

bool cmp(Edge a,Edge b)
{
  return a.v<b.v;
}

int main()
{
  //freopen("graph.in","r",stdin);
  //freopen("graph.out","w",stdout);
  scanf("%d%d",&n,&m);
  for(int i=1;i<=n;i++) scanf("%lld%lld",&p[i].x,&p[i].y);
  for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) addedge(i,j,(p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y));
  sort(e+1,e+cnt+1,cmp);
  for(int i=1;i<=m;i++)
  {
    int nowsize;
    scanf("%d%lld",&nowsize,&cpo[i].v);
    for(int j=1;j<=nowsize;j++)
    {
      int now;
      scanf("%d",&now);
      cpo[i].vp.push_back(now);
    }
  }
  for(int j=1;j<=n;j++)
  {
    f[j]=j;
    size[j]=1;
  }
  edgecnt=0;
  for(int j=1;j<=cnt&&edgecnt<n-1;j++) if(merge(e[j].a,e[j].b)) ep[++cnt2]=e[j];
  int tvt=(1<<(m))-1;
  for(int i=0;i<=tvt;i++)
  {
    long long nowans=0;
    for(int j=1;j<=n;j++)
    {
      f[j]=j;
      size[j]=1;
    }
    edgecnt=0;
    for(int j=1;j<=m;j++)
    {
      if(i&(1<<(j-1)))
      {
        nowans+=cpo[j].v;
        for(int k=1;k<cpo[j].vp.size();k++)
        {
          merge(cpo[j].vp[k],cpo[j].vp[0]);
        }
      }
    }
    for(int j=1;j<=cnt2&&edgecnt<n-1;j++) if(merge(ep[j].a,ep[j].b)) nowans+=ep[j].v;
    if(nowans<ans) ans=nowans;
  }
  printf("%lld",ans);
}

T3

正解是类似于Zuma一样的状态设计,自己打了一个分颜色讨论的dp,不知道为啥没过

考虑dp[i][j][k]表示\([i,j]\)区间,并且后面跟随\(k\)个和\(r\)当前颜色相同的球的贡献

posted @ 2020-10-20 16:38  zzqDeco  阅读(63)  评论(0编辑  收藏  举报