2015年百度之星程序设计大赛 - 初赛(2)
目前只会四道--》
1002:很明显的MST 把,但是注意不要每个点都连接四条边,会爆内存。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include<cmath> 5 #include <algorithm> 6 7 typedef long long ll; 8 using namespace std; 9 10 #define N 1011 11 #define inf 0x3f3f3f3 12 typedef long long ll; 13 int f[N*N]; 14 15 int mp[1011][1011]; 16 int idx[1011][1011]; 17 18 int n,m; 19 struct node 20 { 21 int x,y,z; 22 }e[3011111]; 23 24 int dx[]={0,-1}; 25 int dy[]={-1,0}; 26 27 28 int find(int x) 29 { 30 if (x!=f[x]) f[x]=find(f[x]); 31 return f[x]; 32 } 33 34 int cmp(node a,node b) 35 { 36 return a.z<b.z; 37 } 38 39 int main() 40 { 41 42 int cas=0; 43 int T; 44 scanf("%d",&T); 45 while (T--) 46 { 47 printf("Case #%d:\n",++cas); 48 scanf("%d%d",&n,&m); 49 int id=0; 50 for (int i=1;i<=n;i++) 51 for (int j=1;j<=m;j++) scanf("%d",&mp[i][j]),idx[i][j]=(++id); 52 53 for (int i=1;i<=n*m;i++) f[i]=i; 54 int t=0; 55 56 for (int i=1;i<=n;i++) 57 for (int j=1;j<=m;j++) 58 { 59 for (int k=0;k<2;k++) 60 { 61 int x=i+dx[k]; 62 int y=j+dy[k]; 63 if (x<=0||x>n||y<=0||y>m) continue; 64 e[++t].x=idx[i][j]; 65 e[t].y=idx[x][y]; 66 e[t].z=abs(mp[i][j]-mp[x][y]); 67 } 68 } 69 ll ans=0; 70 sort(e+1,e+t+1,cmp); 71 for (int i=1;i<=t;i++) 72 { 73 int x=e[i].x; 74 int y=e[i].y; 75 x=find(x); 76 y=find(y); 77 if (x!=y) 78 { 79 ans+=e[i].z; 80 f[x]=y; 81 } 82 } 83 printf("%I64d\n",ans); 84 } 85 return 0; 86 }
1003 真实脑残了,
直接暴力DFS就好了,走过的标记一下不走就好了
一直以为这样会T,被自己的复杂度分析惊呆了
1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 5 int a[505][505]; 6 int b[505][505]; 7 using namespace std; 8 9 void solve(int n,int m) 10 { 11 if(b[n][m]==1)return; 12 if(a[n][m]==1) 13 { 14 b[n][m]=1; 15 if(a[n-1][m-1]==1){a[n][m-1]=a[n-1][m]=1;solve(n,m-1);solve(n-1,m);} 16 if(a[n-1][m+1]==1){a[n-1][m]=a[n][m+1]=1;solve(n-1,m);solve(n,m+1);} 17 if(a[n+1][m-1]==1){a[n][m-1]=a[n+1][m]=1;solve(n,m-1);solve(n+1,m);} 18 if(a[n+1][m+1]==1){a[n][m+1]=a[n+1][m]=1;solve(n,m+1);solve(n+1,m);} 19 } 20 } 21 int main() 22 { 23 int n,m,T,g,n1,m1; 24 int i,j,k,sum; 25 scanf("%d",&T); 26 for(i=1;i<=T;i++) 27 { 28 memset(b,0,sizeof(b)); 29 memset(a,0,sizeof(a)); 30 scanf("%d%d",&n,&m); 31 scanf("%d",&g); 32 for(j=1;j<=g;j++) 33 { 34 scanf("%d%d",&n1,&m1); 35 a[n1][m1]=1; 36 } 37 sum=0; 38 for(j=1;j<=n;j++) 39 for(k=1;k<=m;k++) 40 solve(j,k); 41 for(j=1;j<=n;j++) 42 for(k=1;k<=m;k++) 43 if(a[j][k]==1)sum++; 44 printf("Case #%d:\n",i); 45 printf("%d\n",sum); 46 } 47 }
1004:魔法因子;
数学题,并不会。。
假设我们知道axxxxxxb *val =bxxxxxa;
int tmp= bxxxxxxa-axxxxxxb=(b-a)*(pow(10,len-1)-1);
判断tmp==val-1 就好了,maya,神奇的题解。
然后我们枚举 头尾两个元素,注意,头元素不能为0,尾元素可以我0;
代码没有
1005:
做过!但是并没有出来
我们求最多的a[i],a[j],a[k]是上升,
那么要求a[j]-a[i]>=j-i;假设不改变的元素个数
化简一下a[j]-j>=a[i]-i;明显最长不下降子序列
用户upper_lound()
#include<iostream> #include<string.h> #include<string> #include<math.h> #include<stdio.h> #include<stdlib.h> #include<algorithm> using namespace std; #define N 2234567 int a[N]; int f[N]; void debug() { for (int i=1;i<=5;i++) f[i]=i+2; int idx=lower_bound(f+1,f+6,8)-f; cout<<idx<<endl; } int main() { // debug(); int T; scanf("%d",&T); for (int _=1;_<=T;_++) { int n; printf("Case #%d:\n",_); scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",&a[i]),a[i]-=i; int t=0; for (int i=1;i<=n;i++) { if (t==0) f[++t]=a[i]; else if (f[t]<=a[i]) f[++t]=a[i]; else { int idx=upper_bound(f+1,f+t+1,a[i])-f; f[idx]=a[i]; } } printf("%d\n",n-t); } return 0; }
随性Code