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:
B:
C:
D:
E:
F:
G:
H:
I:
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 ; }
相关文章推荐
- [转]annotation配置springMVC的方法了事务不起作用
- Coderforce 380 C. Sereja and Brackets(线段树)
- 将代码源文件由utf8转为GBK
- IBM招聘JAVA开发(员工推荐)
- 区间调度问题 算法第六集
- 1.开始在leetCode中刷题的一些感受
- Android推送机制
- 题目1032:ZOJ
- Windows 静态库
- IOS消息推送。
- 无法向会话状态服务器发出会话状态请求
- MySQL优化之BTree索引使用规则
- 图像处理
- [转]Linux内核源码详解--iostat
- Dijkstra(变形) POJ 1797 Heavy Transportation
- 使用Memcached提高.NET应用程序的性能
- 页面中如何让标点不出现在行首
- Handler, Loop, MessageQueue的工作原理
- 我们正处于一个绝佳的时期-工业4.0感受
- POJ1836 双向LIS