您的位置:首页 > 其它

ASC 20简要题解

2015-11-27 17:07 162 查看
题目链接

A:暴力kmp,dp计算答案,一个串是循环串当且仅当i%(i-f[i])==0,此时(i-f[i])为最小循环节

B:模拟,注意第二种规则是说,“括号的方向朝着箭头指向的方向”,把“(“当成+1,”)“当成-1,找到前缀和最小的地方,从那里将循环切断即可得到一个必然合法的括号序列

C:树哈希。由于这里数据范围比较小,可以直接用set记录每个节点所有儿子的id.可以看出,两个节点不同意味着要么颜色不同,要么存在儿子不同。因此可以在搞一个map<pair<int,set>,int>map,int >来存所有不同的节点,可以看出比较一次的复杂度是O(sizeof(set))O(sizeof(set)).后面的做法就有很多了,我的方法比较暴力,首先二分答案,然后直接给每个节点一个随几的颜色,dfs的时候,当碰到有相同id的儿子出现时,修改其中一个儿子。修改的方法是暴力去找这棵子树中是否存在一个节点,使得修改这个点的颜色后不会和其他节点产生冲突,如果找不到就返回falsefalse;

代码虽然能过数据,然而有地方写错了,如果有读者发现还请指正。

D:p和q都不会很大,暴力dp即可p和q都不会很大,暴力dp即可

E:可以证明,如果可以合并出来,那么必然可以贪心的按照任意顺序合并出来,因此暴力合并即可

F:dp[i][j]代表分别以i和j作为起点所能产生的最长的平行的街道长度,显然转移的时候可以将i连出去的边和j连出去的边排序之后双指针搞,复杂度就是O(nm)O(nm)

G:可以看出,长度超过20的部分都没用,因此可以记录s[i][j]代表第i个字母做2^j之后产生的字符串,快速幂那样写写就好了

H:暴力splay模拟

I:二分答案后,可以看出咖啡馆能修在0.5处就修在0.5处,因此只要求一个最大匹配,最少需要的咖啡馆就是总点数-最大匹配,与p比较一下大小即可

J:编译原理式的模拟,还没有补过

A:

#include<bits/stdc++.h>
using namespace std;
const int Inf=1e9;
char s[5050];
int f[5050];
int dp[5050];
int pre[5050],mul[5050],len[5050];
int ls;
void kmp(char *s)
{
f[0]=f[1]=0;
for(int i=1;s[i];i++)
{
int j=f[i];
while(j&&s[i]!=s[j])j=f[j];
f[i+1]=s[i]==s[j]?j+1:0;
}
}
int main()
{
freopen("decomp.in","r",stdin);
freopen("decomp.out","w",stdout);
scanf("%s",s+1);
ls=strlen(s+1);
for(int i=1;i<=ls;i++)dp[i]=Inf;
dp[0]=0;
for(int i=0;i<ls;i++)
{
kmp(s+i+1);
for(int j=1;j<=ls-i;j++)
{
if(j%(j-f[j])==0)
{
if(dp[i+j]>dp[i]+j-f[j])
{
dp[i+j]=dp[i]+j-f[j];
pre[i+j]=i;
len[i+j]=(j-f[j]);
mul[i+j]=j/(j-f[j]);
}
}
}
}
vector<string>V1;
vector<int>V2;
for(int now=ls;now;now=pre[now])
{
V2.push_back(mul[now]);
string tp;
for(int i=pre[now]+1;i<=pre[now]+len[now];i++)tp.push_back(s[i]);
V1.push_back(tp);
}
reverse(V1.begin(),V1.end());
reverse(V2.begin(),V2.end());
printf("%d\n",dp[ls]);
for(int i=0;i<V1.size();i++)
{
cout<<V1[i]<<" "<<V2[i]<<endl;
}
}


B:

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int>pi;
const int Maxn=400020,Maxe=400020;
typedef pair<int,int>pi;
int n;
vector<int>G[Maxn];
int id[Maxn];//A->B
int ne;
int done[Maxn];
int rev[Maxn];
int eu[Maxe],ev[Maxe],ety[Maxe],w[Maxe],ans[Maxe];
void add(int u,int v,int ty)
{
eu[ne]=u,ev[ne]=v,ety[ne]=ty;
w[ne]=0;
G[u].push_back(ne++);
eu[ne]=v,ev[ne]=u,ety[ne]=ty;
w[ne]=1;
G[v].push_back(ne++);
}
void solve(int st)
{
//printf("st=%d\n",st);
vector<int>V;
V.push_back(G[st][0]);
int x=ev[G[st][0]],last=G[st][0];
int rep[2];
rep[0]=rep[1]=0;
rep[w[G[st][0]]]++;
for(;x!=st;)
{
//printf("x=%d\n",x);
if(G[x][0]!=(last^1))
{
V.push_back(G[x][0]);
last=G[x][0];
rep[w[G[x][0]]]++;
x=ev[G[x][0]];
}
else
{

V.push_back(G[x][1]);
last=G[x][1];
rep[w[G[x][1]]]++;
x=ev[G[x][1]];
}
}
for(int i=0;i<V.size();i++)
{
done[eu[V[i]]]=done[ev[V[i]]]=1;
}
if(rep[0]!=rep[1])
{
if(rep[0]>rep[1])
{
for(int i=0;i<V.size();i++)
{
int idx=V[i];
if(!ety[idx])
{
ans[ev[idx]>>1]=id[ev[V[(i+1)%V.size()]]];
}
}
}
else
{
for(int i=0;i<V.size();i++)
{
int idx=V[i];
if(!ety[idx])
{
ans[ev[idx]>>1]=id[ev[V[(i-1+V.size())%V.size()]]];
}
}
}
}
else
{
int minval=1e9,loc=-1;
int cur=0;
for(int i=0;i<V.size();i++)
{
int idx=V[i];
cur+=w[idx]?1:-1;
if(cur<minval)
{
minval=cur;
loc=i;
}
}
vector<int>V2;
for(int i=(loc+1)%V.size();i!=loc;i=(i+1)%V.size())
{
V2.push_back(V[i]);
}
V2.push_back(V[loc]);
vector<int>V3;
for(int i=0;i<V2.size();i++)
{
int idx=V2[i];
if(w[idx])V3.push_back(V2[i]);
else
{
int id1=V2[i],id2=V3.back();
if(ety[id1])swap(id1,id2);
ans[ev[id1]>>1]=id[ev[id2]];
V3.pop_back();
}
}
}
}
int main()
{
freopen("divide.in","r",stdin);
freopen("divide.out","w",stdout);
scanf("%d",&n);
for(int i=0;i<n+n;i++)
{
int ty,u;
scanf("%d%d",&ty,&u);
u--;
id[i]=u<<1|ty;
rev[u<<1|ty]=i;
}

ne=0;
for(int i=0;i<n;i++)
{
add(i<<1,i<<1|1,0);
}
for(int i=0;i<n;i++)
{
int u=rev[i<<1],v=rev[i<<1|1];
add(u,v,1);
}

for(int i=0;i<n+n;i++)
{
if(!done[i])
{
solve(i);
}
}

for(int i=0;i<n;i++)printf("%d\n",(ans[i]>>1)+1);
}


C:

#include<bits/stdc++.h>
using namespace std;
const int Maxn=555;
typedef vector<int> vv;
typedef set<int>ss;
typedef set<int>::iterator iter;
typedef pair<int,ss> pi;
bool operator<(const ss&a,const ss&b)
{
if(a.size()!=b.size())return a.size()<b.size();
for(iter it1=a.begin(),it2=b.begin();it1!=a.end();it1++,it2++)
{
if(*it1!=*it2)return *it1<*it2;
}
return 0;
}
int col[Maxn],id[Maxn],f[Maxn];
map<pi,int>Mp;
vv G[Maxn];
ss dp[Maxn];
int n;
int tot,cnt;
bool fuck;
void debug(){puts("wa");exit(0);}
int getcol()
{
return rand()%tot+1;
}
int getid(int x)
{
if(Mp.find(pi(col[x],dp[x]))==Mp.end())
{
Mp[pi(col[x],dp[x])]=++cnt;
return cnt;
}
return Mp[pi(col[x],dp[x])];
}

bool dfs2(int u,int st)
{
for(int i=1;i<=tot;i++)
{
if(col[u]==i)continue;
if(Mp.find(pi(i,dp[u]))==Mp.end())
{
Mp[pi(i,dp[u])]=++cnt;
col[u]=i;
id[u]=cnt;
return 1;
}
else
{
int nid=Mp[pi(i,dp[u])];
bool flag=1;
int tpid=nid;
for(int j=u;j!=st;j=f[j])
{
if(dp[f[j]].find(tpid)!=dp[f[j]].end()){flag=0;break;}
if(f[j]==st)break;
int storeid=id[j];
dp[f[j]].erase(storeid);
dp[f[j]].insert(tpid);
if(Mp.find(pi(col[f[j]],dp[f[j]]))==Mp.end())
{
dp[f[j]].erase(tpid);
dp[f[j]].insert(storeid);
break;
}
int nxtid=getid(f[j]);
dp[f[j]].erase(tpid);
dp[f[j]].insert(storeid);
tpid=nxtid;
}
if(flag)
{
col[u]=i;
id[u]=nid;
return 1;
}
}
}
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i];
int tpid=id[v];
if(dfs2(v,st))
{
dp[u].erase(tpid);
dp[u].insert(id[v]);
id[u]=getid(u);
return 1;
}
}
return 0;
}
bool dfs(int u)
{
col[u]=getcol();
dp[u].clear();
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if(!dfs(v))return 0;
if(dp[u].find(id[v])!=dp[u].end())
{
if(!dfs2(v,u))return 0;
}
dp[u].insert(id[v]);
}
id[u]=getid(u);
if(fuck&&u==1)
{
printf("dp1.size=%d G1.size=%d\n",(int)dp[1].size(),(int)G[1].size());
}
return 1;
}
bool check(int mid)
{
tot=mid;
Mp.clear();
cnt=0;
if(dfs(1))return 1;
return 0;
}
int main()
{
freopen("doityourself.in","r",stdin);
freopen("doityourself.out","w",stdout);
//srand(time(NULL));
scanf("%d",&n);
for(int i=2;i<=n;i++)
{
int x;scanf("%d",&x);
f[i]=x;
G[x].push_back(i);
}
if(check(1))
{
puts("1");
for(int i=1;i<=n;i++)
printf("1%c",i==n?'\n':' ');
return 0;
}
int L=1,R=n;
while(L+1<R)
{
int mid=(L+R)>>1;
if(check(mid))R=mid;
else L=mid;
}
check(R);
check(R);
for(int i=1;i<=n;i++)
{
if(G[i].size()!=dp[i].size())
{
fuck=1;
check(R);
printf("%d %d\n",(int)G[1].size(),(int)dp[1].size());
return 0;
}
}
printf("%d\n",R);
for(int i=1;i<=n;i++)
{
printf("%d%c",col[i],i==n?'\n':' ');
}
}


D:

#include <bits/stdc++.h>
using namespace std ;

typedef long long LL ;

#define clr( a , x ) memset ( a , x , sizeof a )

const int MAXN = 5005 ;
const int INF = 0x3f3f3f3f ;

LL n ;
int w[10000][2] ;
LL dp[100][100] ;

int solve () {
int k = 0 ;
for ( int i = 2 ; i <= 1000000 ; ++ i ) {
if ( n % i == 0 ) {
while ( n % i == 0 ) {
k ++ ;
n /= i ;
}
break ;
}
}
if ( !k ) printf ( "1\n" ) ;
else {
int m = 0 ;
for ( int i = 0 ; i <= k ; ++ i ) {
for ( int j = 0 ; j <= k ; ++ j ) if ( i || j ) {
w[m][0] = i ;
w[m][1] = j ;
++ m ;
}
}
clr ( dp , 0 ) ;
dp[0][0] = 1 ;
for ( int i = 0 ; i < m ; ++ i ) {
for ( int x = w[i][0] ; x <= k ; ++ x ) {
for ( int y = w[i][1] ; y <= k ; ++ y ) {
dp[x][y] += dp[x - w[i][0]][y - w[i][1]] ;
}
}
}
printf ( "%lld\n" , dp[k][k] - 1 ) ;
}
}

int main () {
freopen ( "false.in" , "r" , stdin ) ;
freopen ( "false.out" , "w" , stdout ) ;
while ( ~scanf ( "%lld" , &n ) ) solve () ;
return 0 ;
}


E:

#include <bits/stdc++.h>
using namespace std ;

typedef long long LL ;

#define clr( a , x ) memset ( a , x , sizeof a )

const int MAXN = 405 ;
const int INF = 0x3f3f3f3f ;

struct Node {
int nxt , val ;
} ;

Node node[MAXN] ;
int cur ;
int G[MAXN][MAXN] ;
int a[MAXN][MAXN] , cnt[MAXN] ;
int n , k ;

void solve () {
for ( int i = 1 ; i <= n ; ++ i ) {
getchar () ;
for ( int j = 1 ; j <= n ; ++ j ) {
char c = getchar () ;
G[i][j] = c == '-' ;
}
}
for ( int i = 1 ; i < n ; ++ i ) {
G[i]
= 1 ;
}
for ( int i = 1 ; i <= k ; ++ i ) {
for ( cnt[i] = 0 ; ; cnt[i] ++ ) {
scanf ( "%d" , &a[i][cnt[i]] ) ;
if ( a[i][cnt[i]] == n ) break ;
}
-- cnt[i] ;
}
for ( int i = 0 ; i <= cnt[1] ; ++ i ) {
++ cur ;
node[cur].nxt = cur + 1 ;
node[cur].val = a[1][i] ;
}
++ cur ;
node[cur].nxt = 0 ;
node[cur].val = n ;
for ( int i = 2 ; i <= k ; ++ i ) {
for ( int j = 1 , o = 1 ; j <= cnt[i] ; ++ j ) {
for ( ; node[o].nxt ; o = node[o].nxt ) {
int x = node[o].val ;
int y = node[node[o].nxt].val ;
int z = a[i][j] ;
if ( G[x][z] && G[z][y] ) {
++ cur ;
node[cur].nxt = node[o].nxt ;
node[o].nxt = cur ;
node[cur].val = z ;
o = cur ;
break ;
}
}
}
}
for ( int o = 1 ; node[o].nxt ; o = node[o].nxt ) {
printf ( "%d " , node[o].val ) ;
}
printf ( "%d\n" , n ) ;
}

int main () {
freopen ( "inspection.in" , "r" , stdin ) ;
freopen ( "inspection.out" , "w" , stdout ) ;
while ( ~scanf ( "%d%d" , &n , &k ) ) solve () ;
return 0 ;
}


F:

#include <bits/stdc++.h>
using namespace std ;

typedef long long LL ;

#define clr( a , x ) memset ( a , x , sizeof a )

const int MAXN = 405 ;
const int INF = 0x3f3f3f3f ;
const double eps = 1e-10 ;

struct Point {
int x , y ;
Point () {}
Point ( int x , int y ) : x ( x ) , y ( y ) {}
Point operator - ( const Point& b ) const {
return Point ( x - b.x , y - b.y ) ;
}
int len2 () {
return x * x + y * y ;
}
} ;

struct Node {
int v , dis ;
double r ;
Node () {}
Node ( int v , double r , int dis ) : v ( v ) , r ( r ) , dis ( dis ) {}
bool operator < ( const Node& a ) const {
return r < a.r ;
}
} ;

Point p[MAXN] ;
vector < Node > X[MAXN] , Y[MAXN] ;
int pre[2][MAXN][MAXN][2] ;
int n , m ;
double dp[MAXN][MAXN] ;
bool vis[MAXN][MAXN] ;
int ans1 , ans2 , ways ;
vector < int > S1 , S2 ;

int sgn ( double x ) {
return ( x > eps ) - ( x < -eps ) ;
}

double dfs ( int x , int y , vector < Node > G[] , int f ) {
if ( vis[x][y] ) return dp[x][y] ;
vis[x][y] = 1 ;
double ans = 0 ;
for ( int i = 0 , j = 0 ; i < G[x].size () ; ++ i ) {
while ( j < G[y].size () && G[y][j].r < G[x][i].r ) ++ j ;
if ( j == G[y].size () ) break ;
if ( G[x][i].dis != G[y][j].dis || sgn ( G[y][j].r - G[x][i].r ) ) continue ;
double tmp = sqrt ( 0.0 + G[x][i].dis ) + dfs ( G[x][i].v , G[y][j].v , G , f ) ;
if ( ans < tmp ) {
ans = tmp ;
pre[f][x][y][0] = G[x][i].v ;
pre[f][x][y][1] = G[y][j].v ;
}
}
return dp[x][y] = ans ;
}

int get ( int f , int x , int y ) {
S1.push_back ( x ) ;
S2.push_back ( y ) ;
if ( pre[f][x][y][0] ) return get ( f , pre[f][x][y][0] , pre[f][x][y][1] ) + 1 ;
return 1 ;
}

void solve () {
int x , y ;
for ( int i = 1 ; i <= n ; ++ i ) {
scanf ( "%d%d" , &p[i].x , &p[i].y ) ;
X[i].clear () ;
Y[i].clear () ;
}
for ( int i = 1 ; i <= m ; ++ i ) {
scanf ( "%d%d" , &x , &y ) ;
if ( p[x].x > p[y].x ) swap ( x , y ) ;
if ( p[x].x < p[y].x ) {
double r = atan2 ( p[y].y - p[x].y , p[y].x - p[x].x ) ;
X[x].push_back ( Node ( y , r , ( p[y] - p[x] ).len2 () ) ) ;
}
if ( p[x].y > p[y].y ) swap ( x , y ) ;
if ( p[x].y < p[y].y ) {
double r = atan2 ( p[y].y - p[x].y , p[y].x - p[x].x ) ;
Y[x].push_back ( Node ( y , r , ( p[y] - p[x] ).len2 () ) ) ;
}
}
for ( int i = 1 ; i <= n ; ++ i ) {
sort ( X[i].begin () , X[i].end () ) ;
sort ( Y[i].begin () , Y[i].end () ) ;
}
double ans = 0 , ans1 , ans2 ;
clr ( vis , 0 ) ;
clr ( pre , 0 ) ;
for ( int i = 1 ; i <= n ; ++ i ) {
for ( int j = 1 ; j <= n ; ++ j ) if ( i != j && !vis[i][j] ) {
dp[i][j] = dfs ( i , j , X , 0 ) ;
if ( ans < dp[i][j] ) {
ans = dp[i][j] ;
ans1 = i ;
ans2 = j ;
ways = 0 ;
}
}
}
clr ( vis , 0 ) ;
for ( int i = 1 ; i <= n ; ++ i ) {
for ( int j = 1 ; j <= n ; ++ j ) if ( i != j && !vis[i][j] ) {
dp[i][j] = dfs ( i , j , Y , 1 ) ;
if ( ans < dp[i][j] ) {
ans = dp[i][j] ;
ans1 = i ;
ans2 = j ;
ways = 1 ;
}
}
}
if ( ans < eps ) printf ( "%.10f\n" , 0.0 ) ;
else {
S1.clear () ;
S2.clear () ;
int cnt = get ( ways , ans1 , ans2 ) ;
printf ( "%.10f\n" , ans ) ;
printf ( "%d\n" , cnt ) ;
for ( int i = 0 ; i < cnt ; ++ i ) {
printf ( "%d%c" , S1[i] , i < cnt - 1 ? ' ' : '\n' ) ;
}
for ( int i = 0 ; i < cnt ; ++ i ) {
printf ( "%d%c" , S2[i] , i < cnt - 1 ? ' ' : '\n' ) ;
}
}
}

int main () {
freopen ( "london.in" , "r" , stdin ) ;
freopen ( "london.out" , "w" , stdout ) ;
while ( ~scanf ( "%d%d" , &n , &m ) ) solve () ;
return 0 ;
}


G:

#include<bits/stdc++.h>
using namespace std;
int n,k,p;
string s[12];
string dp[2][12];
int main()
{
freopen("morpher.in","r",stdin);
freopen("morpher.out","w",stdout);
scanf("%d%d%d",&n,&k,&p);
for(int i=0;i<=n;i++)cin>>s[i];
for(int i=0;i<=n;i++)
{
if(s[i].size()>p)s[i].resize(p);
dp[0][i]=s[i];
}
int cs=0;
for(;k;)
{
if(k&1)
{
string nxt;
for(int i=0;nxt.size()<p&&i<s[0].size();i++)
{
nxt+=dp[cs][s[0][i]-'A'+1];
}
if(nxt.size()>p)nxt.resize(p);
s[0]=nxt;
}
for(int i=1;i<=n;i++)
{
dp[cs^1][i]="";
for(int j=0;dp[cs^1][i].size()<p&&j<dp[cs][i].size();j++)
{
dp[cs^1][i]+=dp[cs][dp[cs][i][j]-'A'+1];
}
if(dp[cs^1][i].size()>p)dp[cs^1][i].resize(p);
}
cs^=1;
k>>=1;
}
//cout<<s[0]<<endl;
if(s[0].size()>=p)printf("%c\n",s[0][p-1]);
else puts("-");
}


H:

#include <bits/stdc++.h>
using namespace std ;

typedef long long LL ;

#define clr( a , x ) memset ( a , x , sizeof a )

const int MAXN = 233333 ;
const int INF = 0x3f3f3f3f ;

struct Node {
Node* c[2] , *f ;
int s , v ;
int minv ;

void up () {
s = c[0]->s + c[1]->s + 1 ;
minv = min ( v , min ( c[0]->minv , c[1]->minv ) ) ;
}
} Tnull , *null = &Tnull ;

struct Splay {
Node node[MAXN] , *cur ;
Node* root ;

void clear () {
null->s = 0 ;
null->v = -1 ;
null->minv = INF ;
cur = node ;
root = null ;
}

Node* newNode ( int v , Node* f ) {
cur->v = v ;
cur->s = 1 ;
cur->minv = v ;
cur->c[0] = cur->c[1] = null ;
cur->f = f ;
return cur ++ ;
}

void rot ( Node* o , bool d ) {
Node* p = o->f ;
p->c[!d] = o->c[d] ;
if ( o->c[d] != null ) o->c[d]->f = p ;
o->f = p->f ;
if ( p->f != null ) {
if ( p == p->f->c[0] ) p->f->c[0] = o ;
else p->f->c[1] = o ;
}
o->c[d] = p ;
p->f = o ;
p->up () ;
if ( root == p ) root = o ;
}

void splay ( Node* o , Node* f ) {
while ( o->f != f ) {
Node* p = o->f ;
if ( p->f == f ) rot ( o , o == p->c[0] ) ;
else {
if ( p == p->f->c[0] ) {
if ( o == p->c[0] ) rot ( p , 1 ) , rot ( o , 1 ) ;
else rot ( o , 0 ) , rot ( o , 1 ) ;
} else {
if ( o == p->c[1] ) rot ( p , 0 ) , rot ( o , 0 ) ;
else rot ( o , 1 ) , rot ( o , 0 ) ;
}
}
}
o->up () ;
}

void select ( int k , Node* f ) {
Node* o = root ;
++ k ;
while ( o != null ) {
int s = o->c[0]->s ;
if ( k == s + 1 ) break ;
if ( k <= s ) o = o->c[0] ;
else {
k -= s + 1 ;
o = o->c[1] ;
}
}
splay ( o , f ) ;
}

Node* get ( int l , int r ) {
select ( l - 1 , null ) ;
select ( r + 1 , root ) ;
return root->c[1]->c[0] ;
}

void insert ( int pos , int v ) {
get ( pos + 1 , pos ) ;
Node* o = newNode ( v , root->c[1] ) ;
root->c[1]->c[0] = o ;
root->c[1]->up () ;
root->up () ;
}
void init () {
clear () ;
root = newNode ( INF , null ) ;
root->c[1] = newNode ( INF , root ) ;
}
} T ;

int n , siz ;

void show () {
for ( int i = 1 ; i <= siz ; ++ i ) {
printf ( "%d " , T.get ( i , i )->v ) ;
}
puts ( "" ) ;
}

void solve () {
char op ;
int x , y ;
T.init () ;
for ( int i = 1 ; i <= n ; ++ i ) {
scanf ( " %c%d%d" , &op , &x , &y ) ;
if ( op == '+' ) T.insert ( x , y ) , ++ siz ;
else printf ( "%d\n" , T.get ( x , y )->minv ) ;
//  show () ;
}
}

int main () {
freopen ( "rmq.in" , "r" , stdin ) ;
freopen ( "rmq.out" , "w" , stdout ) ;
while ( ~scanf ( "%d" , &n ) ) solve () ;
return 0 ;
}


I:

#include <bits/stdc++.h>
using namespace std ;

typedef long long LL ;

#define clr( a , x ) memset ( a , x , sizeof a )

const int MAXN = 505 ;
const int MAXE = 1000005 ;

struct Edge {
int v , n ;
Edge () {}
Edge ( int v , int n ) : v ( v ) , n ( n ) {}
} ;

Edge E[MAXE] ;
int H[MAXN] , cntE ;
int vis[MAXN] , Time ;
int G[MAXN][MAXN] ;
int a[MAXN][4] ;
int use[MAXN] ;
int Ly[MAXN] ;
int c[MAXN] ;
int n , k ;

void init () {
cntE = 0 ;
clr ( H , -1 ) ;
}

void addedge ( int u , int v ) {
E[cntE] = Edge ( v , H[u] ) ;
H[u] = cntE ++ ;
}

int dfs ( int u ) {
for ( int i = H[u] ; ~i ; i = E[i].n ) if ( vis[E[i].v] != Time ) {
int v = E[i].v ;
vis[v] = Time ;
if ( Ly[v] == -1 || dfs ( Ly[v] ) ) {
Ly[v] = u ;
return 1 ;
}
}
return 0 ;
}

int match () {
int ans = 0 ;
Time = 0 ;
clr ( Ly , -1 ) ;
clr ( vis , 0 ) ;
for ( int i = 1 ; i <= n ; ++ i ) if ( c[i] == 1 && use[i] ) {
++ Time ;
ans += dfs ( i ) ;
}
return ans ;
}

bool check ( int x1 , int y1 , int z1 , int x2 , int y2 , int z2 ) {
if ( x1 == x2 && y1 == y2 && abs ( z1 - z2 ) == 1 ) return 1 ;
if ( x1 == x2 && z1 == z2 && abs ( y1 - y2 ) == 1 ) return 1 ;
if ( y1 == y2 && z1 == z2 && abs ( x1 - x2 ) == 1 ) return 1 ;
return 0 ;
}

void paint ( int u ) {
for ( int i = 1 ; i <= n ; ++ i ) if ( G[u][i] ) {
if ( !c[i] ) {
c[i] = 3 - c[u] ;
paint ( i ) ;
}
}
}

int build ( int lim ) {
init () ;
clr ( G , 0 ) ;
for ( int i = 1 ; i <= n ; ++ i ) {
for ( int j = 1 ; j <= n ; ++ j ) if ( i != j ) {
if ( check ( a[i][0] , a[i][1] , a[i][2] , a[j][0] , a[j][1] , a[j][2] ) ) {
if ( a[i][3] + a[j][3] >= lim ) G[i][j] = G[j][i] = 1 ;
}
}
}
clr ( c , 0 ) ;
for ( int i = 1 ; i <= n ; ++ i ) if ( !c[i] ) {
c[i] = 1 ;
paint ( i ) ;
}
clr ( use , 0 ) ;
int cnt = n ;
for ( int i = 1 ; i <= n ; ++ i ) if ( c[i] == 1 ) {
for ( int j = 1 ; j <= n ; ++ j ) if ( c[j] == 2 && G[i][j] ) {
addedge ( i , j ) ;
use[i] = use[j] = 1 ;
}
}
for ( int i = 1 ; i <= n ; ++ i ) if ( !use[i] ) {
cnt -- ;
if ( a[i][3] < lim ) return -1 ;
}
return cnt ;
}

void put ( int x1 , int y1 , int z1 , int x2 , int y2 , int z2 ) {
if ( x1 == x2 && y1 == y2 && abs ( z1 - z2 ) == 1 ) {
printf ( "%d %d %.1f\n" , x1 , y1 , ( z1 + z2 ) / 2.0 ) ;
}
if ( x1 == x2 && z1 == z2 && abs ( y1 - y2 ) == 1 ) {
printf ( "%d %.1f %d\n" , x1 , ( y1 + y2 ) / 2.0 , z1 ) ;
}
if ( y1 == y2 && z1 == z2 && abs ( x1 - x2 ) == 1 ) {
printf ( "%.1f %d %d\n" , ( x1 + x2 ) / 2.0 , y1 , z1 ) ;
}
}

void solve () {
for ( int i = 1 ; i <= n ; ++ i ) {
scanf ( "%d%d%d%d" , &a[i][0] , &a[i][1] , &a[i][2] , &a[i][3] ) ;
}
int l = 1 , r = 1e9 ;
while ( l < r ) {
int m = l + r + 1 >> 1 ;
int x = build ( m ) ;
if ( ~x ) {
int y = match () ;
if ( n - y <= k ) l = m ;
else r = m - 1 ;
} else r = m - 1 ;
}
int x = build ( l ) ;
if ( x == -1 ) printf ( "-1\n" ) ;
else {
int y = match () ;
/*
printf ( "%d %d\n" , x , y ) ;
for ( int i = 1 ; i <= n ; ++ i ) if ( c[i] == 1 ) {
for ( int j = H[i] ; ~j ; j = E[j].n ) {
printf ( "%d %d %d\n" , i , E[j].v , G[i][E[j].v] ) ;
}
}
*/
if ( n - y > k ) printf ( "-1\n" ) ;
else {
printf ( "%d %d\n" , n - y , l ) ;
clr ( vis , 0 ) ;
for ( int i = 1 ; i <= n ; ++ i ) if ( c[i] == 2 ) {
if ( Ly[i] != -1 ) {
int t = Ly[i] ;
vis[t] = 1 ;
put ( a[t][0] , a[t][1] , a[t][2] , a[i][0] , a[i][1] , a[i][2] ) ;
} else {
for ( int j = 1 ; j <= n ; ++ j ) {
if ( !G[j][i] ) continue ;
put ( a[i][0] , a[i][1] , a[i][2] , a[j][0] , a[j][1] , a[j][2] ) ;
break ;
}
}
}
for ( int i = 1 ; i <= n ; ++ i ) if ( c[i] == 1 && use[i] && !vis[i] ) {
for ( int j = 1 ; j <= n ; ++ j ) if ( G[i][j] ) {
put ( a[i][0] , a[i][1] , a[i][2] , a[j][0] , a[j][1] , a[j][2] ) ;
break ;
}
}
for ( int i = 1 ; i <= n ; ++ i ) if ( use[i] == 0 ) {
printf ( "%d %d %d\n" , a[i][0] , a[i][1] , a[i][2] ) ;
}
}
}
}

int main () {
freopen ( "starbugs.in" , "r" , stdin ) ;
freopen ( "starbugs.out" , "w" , stdout ) ;
while ( ~scanf ( "%d%d" , &n , &k ) ) solve () ;
return 0 ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: