11.5 考试
事实证明,freopen是绝对不能错的,否则只有愉快的爆零,爆零……
——11.5 LSY
1st:
暴力模拟
#include<bits/stdc++.h> #define re return #define inc(i,l,r) for(int i=l;i<=r;++i) using namespace std; template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } #define ll long long ll n,len; char s[3000]; inline ll Get_num() { ll ret=0; inc(i,len+1,n) ret=ret*10+(s[i]^48); re ret; } inline int check(ll x) { if(x==1)re 0; if(x==0)re 7; inc(i,1,9) { x=sqrt(x); if(x==1)re i; } } int main() { while(~(scanf("%s",s+1))) { if(s[1]=='E')re 0; n=strlen(s+1); len=0; inc(i,1,n) if(s[i]!='0')break; else ++len; if(n-len>10)puts("TAT"); else { ll x=Get_num(); ll y=check(x); if(y>=6)puts("TAT"); else printf("%lld\n",y); } } re 0; }
2nd:
emmm……
以为打了个暴力程序,枚举m选的集合,结果是正解
N^2*2^m的60pts
因为一句freopen 没了
它没了……
然而正解是很妙的,比如显而易见的只会枚举最先生成树的点
果然,只有优化,就无所不能
#include<bits/stdc++.h> #define re return #define inc(i,l,r) for(int i=l;i<=r;++i) using namespace std; template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } #define ll long long const int maxn=2005; int n,m,fa[maxn],cost[15]; vector<int>G[maxn]; struct POS{ int x,y; }a[maxn]; struct node{ int fr,to,val; inline bool operator<(node b)const {re val<b.val;} }e[maxn*maxn],e1[maxn]; int k,k1; inline int Gdis(int x,int y){re x*x+y*y;} inline void Get_dis(){ inc(i,1,n) inc(j,i+1,n) e[++k]=(node){i,j,Gdis(a[i].x-a[j].x,a[i].y-a[j].y)}; } ll ans,sum; inline int find(int x){re x==fa[x]?x:fa[x]=find(fa[x]);} inline void F_KRUSKAL() { inc(i,1,n)fa[i]=i; inc(i,1,k) { int x=find(e[i].fr),y=find(e[i].to); if(x!=y) { fa[x]=y; e1[++k1]=e[i]; ans+=e[i].val; if(k1==n-1)re ; } } } inline void KRUSKAL() { inc(i,1,k1) { int x=find(e1[i].fr),y=find(e1[i].to); if(x!=y) { fa[x]=y; sum+=e1[i].val; } } } #define lowbit(x) (x&(-x)) int low[30000]; int main() { //freopen("in.txt","r",stdin); rd(n),rd(m); inc(i,1,n){ rd(a[i].x),rd(a[i].y); } int cnt,x,y; inc(i,1,m) { rd(cnt);rd(cost[i]); inc(k,1,cnt) { rd(x); G[i].push_back(x); } } Get_dis(); inc(i,1,m)low[1<<(i-1)]=i; sort(e+1,e+k+1); F_KRUSKAL(); int last; inc(i,1,(1<<m)-1) { inc(j,1,n)fa[j]=j; x=i;sum=0; for(;x;x-=lowbit(x)) { y=low[lowbit(x)]; sum+=cost[y]; for(vector<int>::iterator it=G[y].begin();it!=G[y].end();++it) { int now=*it; if(it!=G[y].begin())fa[find(now)]=find(last); last=now; } } KRUSKAL(); ans=min(ans,sum); } printf("%lld",ans); re 0; }
3rd:
虽然我知道他肯定不只是个二维DP,就能解决的事,
这第三维我肯定想不出来
不过玄学的伪三维dp(二维简化版)竟然有50pts,震惊??
#include<bits/stdc++.h> #define re return #define inc(i,l,r) for(int i=l;i<=r;++i) using namespace std; template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } const int maxn=305; int n,m,a[maxn],f[maxn][maxn][maxn],len[maxn],c[maxn],sum[maxn],L[maxn],last[maxn]; int main() { freopen("in.txt","r",stdin); int tot=0;rd(n); inc(i,1,n)rd(a[i]); inc(i,1,n) { c[++tot]=a[i]; len[tot]=1; while(a[i+len[tot]]==a[i]) ++len[tot]; i=i+len[tot]-1;sum[tot]=i; } inc(i,1,tot) { L[i]=last[c[i]]; last[c[i]]=i; } int p; inc(kk,0,tot-1) inc(i,1,tot-kk) { int j=i+kk; inc(k,0,n-sum[i]) { f[i][j][k]=f[i][j-1][0]+(len[j]+k)*(len[j]+k); p=j; while((p=L[p])&&p>=i) { f[i][j][k]=max(f[i][j][k],f[i][p][len[j]+k]+f[p+1][j-1][0]); } } } printf("%d",f[1][tot][0]); re 0; }
DISS:
第一题有毒吧
什么玄学输入(带前导零),只有一个数据点,还有诡奇的题面