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\)当前颜色相同的球的贡献