题面:https://www.cnblogs.com/Juve/articles/11678564.html
简单的操作:
考场上sb了,没看出来
如果有奇环一定不能缩成一条链,判掉奇环后就是bfs最短路了
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 const int MAXN=1005; 8 const int MAXM=1e5+5; 9 int n,m,col[MAXN],tot=0,ans=0,bel[MAXN],res[MAXN]; 10 int to[MAXM<<1],nxt[MAXM<<1],pre[MAXN],cnt=1; 11 void add(int u,int v){ 12 ++cnt,to[cnt]=v,nxt[cnt]=pre[u],pre[u]=cnt; 13 } 14 bool dfs(int x,int c){ 15 col[x]=c,bel[x]=tot; 16 for(int i=pre[x];i;i=nxt[i]){ 17 int y=to[i]; 18 if(col[y]==c) return 0; 19 else if((!col[y])&&(!dfs(y,3-c))) return 0; 20 } 21 return 1; 22 } 23 int dis[MAXN]; 24 void bfs(int st){ 25 memset(dis,0,sizeof(dis)); 26 queue<int>q; 27 dis[st]=1; 28 q.push(st); 29 while(!q.empty()){ 30 int x=q.front(); 31 q.pop(); 32 for(int i=pre[x];i;i=nxt[i]){ 33 int y=to[i]; 34 if(dis[y]==0){ 35 dis[y]=dis[x]+1; 36 q.push(y); 37 } 38 } 39 } 40 } 41 int main(){ 42 scanf("%d%d",&n,&m); 43 for(int i=1,u,v;i<=m;++i){ 44 scanf("%d%d",&u,&v); 45 add(u,v),add(v,u); 46 } 47 for(int i=1;i<=n;++i){ 48 if(!col[i]){ 49 ++tot; 50 if(!dfs(i,1)){ 51 ans=-1; 52 break; 53 } 54 } 55 } 56 if(ans==-1){ 57 printf("%d ",ans); 58 return 0; 59 } 60 for(int i=1;i<=n;++i){ 61 bfs(i); 62 for(int j=1;j<=n;++j){ 63 res[bel[i]]=max(res[bel[i]],dis[j]-1); 64 } 65 } 66 for(int i=1;i<=tot;++i){ 67 ans+=res[i]; 68 } 69 printf("%d ",ans); 70 return 0; 71 }
2048:
话说我不会2048考场上是不是爆0了?
就是模拟
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 int n,m,mp[10][10],ans=0; 7 bool flag=0,vis[10][10]; 8 int get(){ 9 int res=0; 10 for(int i=1;i<=n;++i){ 11 for(int j=1;j<=n;++j) 12 res+=(mp[i][j]==0); 13 } 14 return res; 15 } 16 void put(int pos,int val){ 17 for(int i=1;i<=n;++i){ 18 for(int j=1;j<=n;++j){ 19 if(mp[i][j]!=0) continue; 20 --pos; 21 if(pos==0){ 22 mp[i][j]=val; 23 return ; 24 } 25 } 26 } 27 } 28 void mergeup(){ 29 for(int i=2;i<=n;++i){ 30 for(int j=1;j<=n;++j){ 31 if(mp[i][j]==0) continue; 32 int p=i-1,k=mp[i][j]; 33 while(p>0&&mp[p][j]==0) mp[p][j]=k,mp[p+1][j]=0,--p; 34 if(p!=i-1) flag=1; 35 if(vis[p][j]==0&&mp[p+1][j]==mp[p][j]) mp[p][j]<<=1,mp[p+1][j]=0,flag=vis[p][j]=1,ans+=mp[p][j]; 36 } 37 } 38 } 39 void up(){ 40 for(int i=2;i<=n;++i){ 41 for(int j=1;j<=n;++j){ 42 if(mp[i][j]==0) continue; 43 int p=i-1,k=mp[i][j]; 44 while(p>0&&mp[p][j]==0) mp[p][j]=k,mp[p+1][j]=0,--p; 45 if(p!=i-1) flag=1; 46 } 47 } 48 } 49 void mergedown(){ 50 for(int i=n-1;i>=1;--i){ 51 for(int j=1;j<=n;++j){ 52 if(mp[i][j]==0) continue; 53 int p=i+1,k=mp[i][j]; 54 while(p<=n&&mp[p][j]==0) mp[p][j]=k,mp[p-1][j]=0,++p; 55 if(p!=i+1) flag=1; 56 if(vis[p][j]==0&&mp[p-1][j]==mp[p][j]) mp[p][j]<<=1,mp[p-1][j]=0,flag=vis[p][j]=1,ans+=mp[p][j]; 57 } 58 } 59 } 60 void down(){ 61 for(int i=n-1;i>=1;--i){ 62 for(int j=1;j<=n;++j){ 63 if(mp[i][j]==0) continue; 64 int p=i+1,k=mp[i][j]; 65 while(p<=n&&mp[p][j]==0) mp[p][j]=k,mp[p-1][j]=0,++p; 66 if(p!=i+1) flag=1; 67 } 68 } 69 } 70 void mergeleft(){ 71 for(int j=2;j<=n;++j){ 72 for(int i=1;i<=n;++i){ 73 if(mp[i][j]==0) continue; 74 int p=j-1,k=mp[i][j]; 75 while(p>0&&mp[i][p]==0) mp[i][p]=k,mp[i][p+1]=0,--p; 76 if(p!=j-1) flag=1; 77 if(vis[i][p]==0&&mp[i][p]==mp[i][p+1]) mp[i][p]<<=1,mp[i][p+1]=0,flag=vis[i][p]=1,ans+=mp[i][p]; 78 } 79 } 80 } 81 void left(){ 82 for(int j=2;j<=n;++j){ 83 for(int i=1;i<=n;++i){ 84 if(mp[i][j]==0) continue; 85 int p=j-1,k=mp[i][j]; 86 while(p>0&&mp[i][p]==0) mp[i][p]=k,mp[i][p+1]=0,--p; 87 if(p!=j-1) flag=1; 88 } 89 } 90 } 91 void mergeright(){ 92 for(int j=n-1;j>=1;--j){ 93 for(int i=1;i<=n;++i){ 94 if(mp[i][j]==0) continue; 95 int p=j+1,k=mp[i][j]; 96 while(p<=n&&mp[i][p]==0) mp[i][p]=k,mp[i][p-1]=0,++p; 97 if(p!=j+1) flag=1; 98 if(vis[i][p]==0&&mp[i][p]==mp[i][p-1]) mp[i][p]<<=1,mp[i][p-1]=0,flag=vis[i][p]=1,ans+=mp[i][p]; 99 } 100 } 101 } 102 void right(){ 103 for(int j=n-1;j>=1;--j){ 104 for(int i=1;i<=n;++i){ 105 if(mp[i][j]==0) continue; 106 int p=j+1,k=mp[i][j]; 107 while(p<=n&&mp[i][p]==0) mp[i][p]=k,mp[i][p-1]=0,++p; 108 if(p!=j+1) flag=1; 109 } 110 } 111 } 112 int main(){ 113 scanf("%d%d",&n,&m); 114 int xx1,yy1,vv1,xx2,yy2,vv2; 115 scanf("%d%d%d%d%d%d",&xx1,&yy1,&vv1,&xx2,&yy2,&vv2); 116 mp[xx1][yy1]=vv1,mp[xx2][yy2]=vv2; 117 for(int i=1,d,k,v;i<=m;++i){ 118 scanf("%d%d%d",&d,&k,&v); 119 memset(vis,0,sizeof(vis)); 120 flag=0; 121 if(d==0) mergeup(),up(); 122 if(d==1) mergedown(),down(); 123 if(d==2) mergeleft(),left(); 124 if(d==3) mergeright(),right(); 125 if(!flag){ 126 printf("%d %d ",i-1,ans); 127 return 0; 128 } 129 put(k%get()+1,v); 130 } 131 printf("%d %d ",m,ans); 132 return 0; 133 }
数列:
可以证明最优答案要么是单增,要么先增后减
然后就是最长上升子序列了,好像也不太一样,都差不多
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define int long long 6 using namespace std; 7 const int MAXN=1e5+5; 8 int n,a[MAXN],b[MAXN],f[MAXN],g[MAXN],mx=0; 9 int lsh[MAXN]; 10 double ans=0.0; 11 struct BIT{ 12 int c[MAXN]; 13 int lowbit(int x){ 14 return x&(-x); 15 } 16 int update(int pos,int val){ 17 for(int i=pos;i<=mx;i+=lowbit(i)){ 18 c[i]=max(c[i],val); 19 } 20 } 21 int query(int pos){ 22 int res=0; 23 for(int i=pos;i>0;i-=lowbit(i)){ 24 res=max(res,c[i]); 25 } 26 return res; 27 } 28 }t1,t2; 29 double max(double a,double b){ 30 return a>b?a:b; 31 } 32 signed main(){ 33 scanf("%lld",&n); 34 for(int i=1;i<=n;++i){ 35 scanf("%lld",&a[i]); 36 lsh[i]=a[i]; 37 } 38 sort(lsh+1,lsh+n+1); 39 mx=unique(lsh+1,lsh+n+1)-lsh-1; 40 for(int i=1;i<=n;++i) b[i]=lower_bound(lsh+1,lsh+mx+1,a[i])-lsh; 41 for(int i=1;i<=n;++i){ 42 f[i]=t1.query(b[i]-1)+a[i]; 43 g[i]=t2.query(b[n-i+1]-1)+a[n-i+1]; 44 t1.update(b[i],f[i]); 45 t2.update(b[n-i+1],g[i]); 46 } 47 for(int i=1;i<=n;++i) 48 ans=max(ans,max(f[i],(f[i]+g[n-i+1]-a[i])/2.0)); 49 printf("%0.3lf ",ans); 50 return 0; 51 }
生成树:
连虚数都出来了。。。
把每一个虚数看作向量,枚举角度更新答案
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 const int MAXN=55; 8 const int MAXM=205; 9 int n,m,fa[MAXN]; 10 double ans=0.0,xx,yy; 11 int find(int x){ 12 return fa[x]=(fa[x]==x?x:find(fa[x])); 13 } 14 struct node{ 15 int fr,to; 16 double a,b; 17 friend bool operator < (node p,node q){ 18 return p.a*xx+p.b*yy<q.a*xx+q.b*yy; 19 } 20 }e[MAXM]; 21 double kruskal(){ 22 int vala=0,valb=0,sum=0; 23 for(int i=1;i<=n;++i) fa[i]=i; 24 sort(e+1,e+m+1); 25 for(int i=1;i<=m;++i){ 26 int x=find(e[i].fr),y=find(e[i].to); 27 if(x!=y){ 28 fa[x]=y; 29 ++sum,vala+=e[i].a,valb+=e[i].b; 30 if(sum==n-1) break; 31 } 32 } 33 return sqrt(vala*vala+valb*valb); 34 } 35 int main(){ 36 scanf("%d%d",&n,&m); 37 for(int i=1,u,v;i<=m;++i){ 38 double a,b; 39 scanf("%d%d%lf%lf",&u,&v,&a,&b); 40 e[i]=(node){u,v,a,b}; 41 } 42 for(double i=0.0;i<=63.00;i+=0.01){ 43 xx=sin(i),yy=cos(i); 44 ans=max(ans,kruskal()); 45 } 46 printf("%0.6lf ",ans); 47 return 0; 48 }