SGU 乱乱开
本解题报告 乱抄,乱写,随性随心,不喜多喷!
SGU 142:
思路:一个string的字串不会超过2^20个,我们枚举出来就好了。
我出错点:数组RE
1 #include<stdio.h> 2 #include<math.h> 3 #include<algorithm> 4 #include<string.h> 5 #include<string> 6 #include<iostream> 7 #include<set> 8 #include<map> 9 #include<vector> 10 11 using namespace std; 12 typedef long long ll; 13 14 #define N 566666 15 16 int n; 17 char s[N]; 18 bool b[1<<21]; 19 char ss[50]; 20 21 int main() 22 { 23 scanf("%d",&n); 24 scanf("%s",s); 25 int len=20; 26 27 memset(b,false,sizeof(false)); 28 29 int tot=1<<len; 30 31 for (int i=0;i<n;i++) 32 { 33 int num=1; 34 for (int j=0;j<len&&i+j<n;j++) 35 { 36 if (s[i+j]=='a') 37 num<<=1; 38 else num=num*2+1; 39 b[num]=true; 40 } 41 } 42 43 int pos; 44 45 for (int i=2;i<tot;i++) 46 if (!b[i]) 47 { 48 pos=i; 49 break; 50 } 51 52 int num=floor(log(pos)/log(2)); 53 54 printf("%d\n",num); 55 int tmp=num; 56 57 while (pos>1) 58 { 59 if (pos&1) ss[tmp--]='b'; 60 else ss[tmp--]='a'; 61 pos/=2; 62 } 63 64 for (int i=1;i<=num;i++) 65 printf("%c",ss[i]); 66 67 printf("\n"); 68 return 0; 69 } 70 71 72 73 74
SGU 146 你WA的话,精度 ,精度
SGU 172:二分图染色,然后二分图的一边
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<iostream> 5 #include<math.h> 6 #include<stack> 7 #include<string> 8 #include<map> 9 #include<set> 10 #include<vector> 11 12 using namespace std; 13 typedef long long ll; 14 #define N 102222 15 16 vector<int>mp[333]; 17 int vis[333]; 18 19 int col[333]; 20 21 int ans[333]; 22 23 int tmp=0; 24 int flag=0; 25 void dfs(int x) 26 { 27 vis[x]=1; 28 for (int i=0;i<mp[x].size();i++) 29 { 30 int v=mp[x][i]; 31 if (!vis[v]) 32 { 33 col[v]=3-col[x]; 34 dfs(v); 35 } 36 else 37 { 38 if (col[v]==col[x]) 39 { 40 flag=1; 41 return ; 42 } 43 } 44 } 45 } 46 47 int main() 48 { 49 int n,m; 50 scanf("%d%d",&n,&m); 51 52 53 while (m--) 54 { 55 int x,y; 56 scanf("%d%d",&x,&y); 57 mp[x].push_back(y); 58 mp[y].push_back(x); 59 } 60 61 62 for (int i=1;i<=n;i++) 63 if (!vis[i]) 64 { 65 col[i]=1; 66 dfs(i); 67 if (flag) 68 { 69 puts("no"); 70 return 0; 71 } 72 } 73 74 puts("yes"); 75 76 for (int i=1;i<=n;i++) 77 if (col[i]==1) 78 { 79 ans[++tmp]=i; 80 } 81 82 printf("%d\n",tmp); 83 for (int i=1;i<tmp;i++) 84 printf("%d ",ans[i]); 85 86 printf("%d\n",ans[tmp]); 87 88 return 0; 89 }
SGU 149: 经典题,求任意点到树中任意一点的最长距离。
一遍DFS求出一个点,子树在树中的最远和次远距离;
对每个点 求出其父节点的最远距离。dp[father[u]]= max(dp[father[u]],dp[u].first(子树最长)+e.val);(father[u]不再u 的最长路径上)
否则:dp[father[u]]= max(dp[father[u]],dp[u].first(子树次长)+e.val);(father[u]再u 的最长路径上)
1 #include<stdio.h> 2 #include<math.h> 3 #include<algorithm> 4 #include<string.h> 5 #include<string> 6 #include<iostream> 7 #include<set> 8 #include<map> 9 #include<vector> 10 11 using namespace std; 12 typedef long long ll; 13 14 15 #define N 11111 16 int head[N]; 17 struct node 18 { 19 int v,c,next; 20 }e[N<<2]; 21 int tot; 22 23 struct node2 24 { 25 int idx,val; 26 }dp[N][3],p; 27 28 void init() 29 { 30 tot=0; 31 memset(head,-1,sizeof(head)); 32 } 33 34 void add(int u,int v,int c) 35 { 36 e[tot].v=v; 37 e[tot].c=c; 38 e[tot].next=head[u]; 39 40 head[u]=tot++; 41 } 42 43 44 void dfs_son(int u,int pre) 45 { 46 for (int i=head[u];i!=-1;i=e[i].next) 47 { 48 int v=e[i].v; 49 int c=e[i].c; 50 if (v==pre) continue; 51 dfs_son(v,u); 52 p.val=dp[v][0].val+c; 53 p.idx=v; 54 55 if (p.val>dp[u][0].val) 56 { 57 dp[u][1]=dp[u][0]; 58 dp[u][0]=p; 59 } 60 61 else if (p.val>dp[u][1].val) 62 { 63 dp[u][1]=p; 64 } 65 } 66 } 67 68 void dfs_father(int u,int pre) 69 { 70 for (int i=head[u];i!=-1;i=e[i].next) 71 { 72 int v=e[i].v; 73 int c=e[i].c; 74 if (v==pre) continue; 75 int first=dp[u][0].val; 76 int second=dp[u][1].val; 77 78 int idx=dp[u][0].idx; 79 80 if (idx==v) dp[v][2].val = max(dp[v][2].val,second+c); 81 else dp[v][2].val = max(dp[v][2].val,first+c); 82 83 dp[v][2].val=max(dp[v][2].val,dp[u][2].val+c); 84 85 dfs_father(v,u); 86 } 87 } 88 89 90 int main() 91 { 92 93 int n; 94 scanf("%d",&n); 95 init(); 96 97 for (int i=2;i<=n;i++) 98 { 99 int x,y; 100 scanf("%d%d",&x,&y); 101 // add(i,x,y); 102 add(x,i,y); 103 } 104 dfs_son(1,-1); 105 dfs_father(1,-1); 106 for (int i=1;i<=n;i++) 107 printf("%d\n",max(dp[i][0].val,dp[i][2].val)); 108 return 0; 109 } 110 111 112 113 114
SGU 169: 脑洞题,真心脑洞大开题;看到这么大数位的k,就知道有规律,但是想到的还是太浅太浅,我只是往奇偶数上想了
引用一篇blog: http://www.cppblog.com/willing/archive/2010/05/04/114304.html
SGU 143
小型树形DP,如果子树大于0,那么父节点加上就好了,
注意:有一个节点的情况,比如第二个test
1 #include<stdio.h> 2 #include<algorithm> 3 #include<math.h> 4 #include<vector> 5 #include<string.h> 6 #include<string> 7 #include<set> 8 #include<iostream> 9 using namespace std; 10 typedef long long ll; 11 12 #define N 26666 13 vector<int> mp[N]; 14 15 int a[N]; 16 int n; 17 int dp[N]; 18 int vis[N]; 19 20 void dfs(int u) 21 { 22 vis[u]=1; 23 for (int i=0;i<mp[u].size();i++) 24 { 25 int v=mp[u][i]; 26 if (!vis[v]) 27 { 28 dfs(v); 29 if (dp[v]>0) dp[u]+=dp[v]; 30 31 } 32 } 33 34 } 35 36 37 int main() 38 { 39 int n; 40 scanf("%d",&n); 41 42 for (int i=1;i<=n;i++) scanf("%d",&a[i]),dp[i]=a[i]; 43 44 for (int i=1;i<n;i++) 45 { 46 int x,y; 47 scanf("%d%d",&x,&y); 48 mp[x].push_back(y); 49 mp[y].push_back(x); 50 } 51 52 dfs(1); 53 54 int ans=-1234567; 55 56 for (int i=1;i<=n;i++) 57 ans=max(ans,dp[i]); 58 printf("%d\n",ans); 59 return 0; 60 }
SGU 144:
概率题,一个人等待的时间是(Y-X)*60,如果先到的人等待了Zminute,就会离开,求不会离开的概率
画个矩形图。
SGU 134:
求树的重心;
要么是某一个子树的最大节点,要么是包含根的子树;
1 #include<stdio.h> 2 #include<algorithm> 3 #include<math.h> 4 #include<vector> 5 #include<string.h> 6 #include<string> 7 #include<set> 8 #include<map> 9 #include<iostream> 10 #include<set> 11 using namespace std; 12 typedef long long ll; 13 #define N 33333 14 vector<int>mp[N]; 15 int sum[N]; 16 int a[N]; 17 int dp[N]; 18 19 void dfs(int u,int pre) 20 { 21 for (int i=0;i<mp[u].size();i++) 22 { 23 int v=mp[u][i]; 24 if (v==pre) continue; 25 dfs(v,u); 26 sum[u]+=sum[v]; 27 } 28 sum[u]++; 29 } 30 31 int t=0; 32 int ans=1234456; 33 34 void cal(int u,int pre) 35 { 36 int tmp=sum[u]; 37 dp[u]=0; 38 for (int i=0;i<mp[u].size();i++) 39 { 40 int v=mp[u][i]; 41 if (v==pre) continue; 42 cal(v,u); 43 dp[u]=max(dp[u],sum[v]); 44 } 45 46 dp[u]=max(dp[u],sum[1]-sum[u]); 47 if (dp[u]==ans) 48 { 49 ++t; 50 a[t]=u; 51 } 52 else if (dp[u]<ans) 53 { 54 t=1; 55 ans=dp[u]; 56 a[t]=u; 57 } 58 } 59 60 int main() 61 { 62 int n; 63 scanf("%d",&n); 64 for (int i=1;i<n;i++) 65 { 66 int x,y; 67 scanf("%d%d",&x,&y); 68 mp[x].push_back(y); 69 mp[y].push_back(x); 70 } 71 dfs(1,-1); 72 //for (int i=1;i<=n;i++) printf("%d ",sum[i]); 73 cal(1,-1); 74 printf("%d %d\n",ans,t); 75 sort(a+1,a+t+1); 76 for (int i=1;i<t;i++) printf("%d ",a[i]); 77 printf("%d\n",a[t]); 78 return 0; 79 }
SGU 174:
只要判断当前点是否在一个集合中,不包括自己
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <algorithm> 5 #include <vector> 6 #include <queue> 7 #include <set> 8 #include <map> 9 #include <string> 10 #include <math.h> 11 #include <stdlib.h> 12 #include <time.h> 13 #include<string> 14 #include<map> 15 16 using namespace std; 17 #define N 402222 18 typedef long long ll; 19 20 pair<int,int> pt; 21 #define mk make_pair 22 map<pair<int,int>,int>mp; 23 int f[N]; 24 25 int find(int x) 26 { 27 if (f[x]!=x) f[x]=find(f[x]); 28 return f[x]; 29 } 30 31 int main() 32 { 33 int n; 34 scanf("%d",&n); 35 int t=0; 36 for (int i=1;i<=n*2;i++) f[i]=i; 37 38 int ans=0; 39 for (int i=1;i<=n;i++) 40 { 41 int x,y,xx,yy; 42 scanf("%d%d",&x,&y); 43 scanf("%d%d",&xx,&yy); 44 if (!mp[mk(x,y)]) mp[mk(x,y)]=++t; 45 if (!mp[mk(xx,yy)]) mp[mk(xx,yy)]=++t; 46 x=mp[mk(x,y)]; 47 y=mp[mk(xx,yy)]; 48 x=find(x); 49 y=find(y); 50 if (x==y) 51 { 52 ans=i; 53 break; 54 } 55 else f[x]=y; 56 } 57 printf("%d\n",ans); 58 return 0; 59 }