百度之星2017初赛题解(A)

来源:互联网 发布:php客户端开发 编辑:程序博客网 时间:2024/06/06 09:43

T1:

简单数论,问满足(a0+a1*B+...+an*B^n)=a0+a1+...+an(mod P)的P的个数

即满足P|(B-1)a1+(B^2-1)a2+(B^3-1)a3+...,即P|B-1的P的个数

sqrt(B-1)暴力枚举B-1约数即可

T2:

现在给若干个条件,xi=xj或xi≠xj,要你将它们划分成若干组,满足每个组除去最后一个条件时成立,否则不成立。

拿并查集将所有相等的点缩起来,对于每个连通块,挂一个vector或者set储存与他不相等的连通块编号(即并查集的代表元)

启发式合并,每次将vector小的合并到大的中去,复杂度O(nlognα(n))或O(nlog^2nα(n))(实际不满)

PS:SB出题人认为最后一组到最后一个条件若成立就不输出

#include<bits/stdc++.h>#include<tr1/unordered_set>#define maxn 200100using namespace std;typedef long long ll;set<ll>st2[maxn];typedef set<ll>::iterator sit;int L,T,cnt[maxn],f[maxn],A[maxn],B[maxn],C[maxn];int find(int x){return x==f[x]?x:f[x]=find(f[x]);}int main(){    scanf("%d",&L);    for(int i=1;i<=200010;++i)f[i]=i;    for(int i=1;i<=L;++i)        scanf("%d%d%d",&A[i],&B[i],&C[i]);    for(int i=1,pos;i<=L;i=pos){        for(pos=i;pos<=L;pos++){            if(C[pos]){                int x=find(A[pos]),y=find(B[pos]);                if(x==y)continue;                if(st2[x].find(y)!=st2[x].end()){                    cnt[++T]=pos-i+1;                    break;                }                if(st2[x].size()>st2[y].size())swap(x,y);                f[x]=y;                for(sit it=st2[x].begin();it!=st2[x].end();++it)                    st2[*it].erase(x),st2[*it].insert(y),st2[y].insert(*it);                st2[x].clear();            } else {                int x=find(A[pos]),y=find(B[pos]);                if(x==y){                    cnt[++T]=pos-i+1;                    break;                }                st2[x].insert(y),st2[y].insert(x);            }        }        if(pos<=L)pos++;        for(int j=i;j<pos;++j)            st2[A[j]].clear(),st2[B[j]].clear(),f[A[j]]=A[j],f[B[j]]=B[j];    }    printf("%d\n",T);    for(int i=1;i<=T;++i)printf("%d\n",cnt[i]);}

T3:

这个。。。简单题吧,

首先两条路径求交,交集一定是一条路径,一定是一个的LCA在另一条路径上,否则交集就是空

那么维护一个线段树,每个节点表示这个区间的路径求交求出的路径是什么

然后普通线段树那样做即可

T4:

给你个地图(BALABALA...)注意“*”翻转的可达性是所有格子都要翻转

这题。。。如果状压"*"的状态的话,我猜想有用的状态(即可能成为最优)不会很多

于是拿一个hash表spfa暴力DP一番(可能本质上是真·暴力

然后就过了。。。

#include<bits/stdc++.h>#define get(x,y) ((x*100)+y)#define inf 1000000007using namespace std;typedef unsigned long long ull;typedef pair<int,bool> par;ull h(ull id,ull S){return S*19260817+id;}unordered_map<ull,par>dp;queue<pair<int,ull> >q;char c[100][100];int T,n,m,cas,id[100][100],dx[4]={0,0,1,-1},dy[4]={1,-1,0,0},flag,edx,edy;ull pre[100][100];int main(){scanf("%d",&T);while(T--){scanf("%d%d",&n,&m);dp.clear();int ans=inf,x0=0,x1=0,bg,ed;for(int i=1;i<=n;++i){scanf("%s",c[i]+1);for(int j=1;j<=m;++j)if(c[i][j]=='S')bg=get(i,j);else if(c[i][j]=='E')edx=i,edy=j;}x1=0,flag=1;for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)if(c[i][j]=='*')id[i][j]=++x1;else id[i][j]=0;for(int i=1;i<=n;++i)for(int j=1;j<=m;++j){pre[i][j]=0;for(int k=0;k<4;++k){int ni=i+dx[k],nj=j+dy[k];if(ni<=0||nj<=0||ni>n||nj>m)continue;if(c[ni][nj]=='*')pre[i][j]|=1ull<<id[ni][nj];}}q.push(make_pair(bg,0ull)),dp[h(bg,0)].first=1;while(q.size()){pair<int,ull> u=q.front();q.pop();int x,y,p=dp[h(u.first,u.second)].first;ull s;dp[h(u.first,u.second)].second=0;x=u.first/100,y=u.first%100,s=u.second;//printf("<%d,%d,%llu,%d>\n",x,y,s,p);if(p+abs(x-edx)+abs(y-edy)>=ans)continue;for(int i=0;i<4;++i){int nx=x+dx[i],ny=y+dy[i];ull _s=s;if(nx<=0||ny<=0||nx>n||ny>m)continue;if((__builtin_popcount(s&pre[nx][ny])&1)^(c[nx][ny]=='x'))continue;if(c[nx][ny]!='.'&&c[nx][ny]!='x'){if(c[nx][ny]=='E'&&(s&1)){ans=min(ans,p+1);} else if(c[nx][ny]=='*'){_s^=(1ull<<id[nx][ny]);} else if(c[nx][ny]=='K'){_s|=1;}}ull S=h(get(nx,ny),_s);int& _q=dp[S].first;if(!_q||_q>p+1){_q=p+1;if(_q>=ans)continue;if(dp[S].second)continue;dp[S].second=1,q.push(make_pair(get(nx,ny),_s));}}}printf("Case #%d:\n%d\n",++cas,ans==inf?-1:ans-1);}}

T5:

不想说了,2-29写成2-30,智商-1

T6:

不想说了,bfs/dfs判一下连通块即可

#include<bits/stdc++.h>using namespace std;char c[110][110];int n,m,vis[110][110],flag;void dfs(int x,int y,int z){if(vis[x][y])return ;if(x<=0||y<=0||x>n||y>m){flag=1;return ;}if(c[x][y]!=z)return ;vis[x][y]=1;dfs(x+1,y,z),dfs(x,y+1,z),dfs(x-1,y,z),dfs(x,y-1,z);}int main(){while(scanf("%d%d",&n,&m)==2){for(int i=1;i<=n;++i)scanf("%s",c[i]+1);for(int i=0;i<=n+5;++i)for(int j=0;j<=m+5;++j)vis[i][j]=0;int x0=0,x1=0,_x0=0;for(int i=1;i<=n;++i)for(int j=1;j<=m;++j){if(!vis[i][j]){flag=0,dfs(i,j,c[i][j]);if(c[i][j]=='1'){x1++;} else {x0++;if(!flag)_x0++;}}}//printf("[%d,%d,%d]",x0,x1,_x0);if(_x0==1&&x1==1)printf("0\n");else if(_x0==0&&x1==1)printf("1\n");else printf("-1\n");}}


原创粉丝点击