人生第一场SRM SRM695 Div.2
2016-07-19 21:03
344 查看
第一题
模拟题,用x,y分别表示水平位移和垂直位移,然后把这两个利用勾股定理算出直线距离,再加上之前的路程和。#include <vector> #include <list> #include <map> #include <set> #include <queue> #include <deque> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <ctime> using namespace std; class BearNSWE { public: double totalDistance(vector <int> a, string dir) { int c=0,b=0; int ans=0; for(int i=0;i<dir.length();i++){ if(dir[i]=='N') c+=a[i]; if(dir[i]=='S') c-=a[i]; if(dir[i]=='W') b-=a[i]; if(dir[i]=='E') b+=a[i]; ans+=a[i]; } return (double)ans+sqrt(c*c+b*b); } };
第二题
题目大意
一个字符串的字串如果全部相同,叫做好串(乱取的)。两个好串如果起始位置或终止位置不同就算不同。
给定一个数组,表示要求的每个长度的好串个数,给出一组满足条件的解,如果没有输出“”。
要求构造的字符串中只有a和b。
题解
可以从后往前扫过去,如果当前长度的好串不够,那么就补上去,就补当前要求长度个与上一个不同的字符,一直补到够为止。这就可以AC了是不是,然而,我却傻帽了一下,如果有很多组,我就在它们之间插入一个单独的字符,阻断两个字符串,结果光荣地没过system test。
给个大数据:
50, 48, 46, 44, 42, 40, 38, 36, 34, 32, 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
答案是有的,比如:
aaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbb
但我的程序输出“”。
还有一个错误,就是我只要判断当前点的x[i]==0就continue,但是没有想到还有可能当前的这个长度的好串已经大于要求的值了。
比如对于3 0 1 这个数据。
构造到0是已经有2个长度为2的好串了,这是应该返回“”,然而,我的代码却continue了。
#include <vector> #include <list> #include <map> #include <set> #include <queue> #include <deque> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <ctime> using namespace std; class BearPasswordAny { public: string findPassword(vector <int> x) { char str[3]={"ab"}; int n=x.size(); if(x[0]!=n) return ""; int sum=0; for(int i=0;i<n;i++) sum+=x[i]; string ans; int cur=0; if(sum==x[0]){ for(int i=0;i<n;i++) ans+=str[cur],cur^=1; return ans; } int tot=0,cnt=0; for(int i=n-1;i>0;i--){ if(x[i]<tot) return ""; if(x[i]){ if(x[i]<tot) return ""; int del=x[i]-tot; cnt+=del; tot+=del; while(del){ cur^=1; for(int j=0;j<=i;j++) ans+=str[cur]; del--; } } tot+=cnt; } while(ans.length()<n){ cur^=1; ans+=str[cur]; } if(ans.length()>n) return ""; return ans; } };
错误代码
#include <vector> #include <list> #include <map> #include <set> #include <queue> #include <deque> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <ctime> using namespace std; class BearPasswordAny { public: string findPassword(vector <int> x) { char str[3]={"ab"}; int n=x.size(); if(x[0]!=n) return ""; int sum=0; for(int i=0;i<n;i++) sum+=x[i]; string ans; int cur=0; if(sum==x[0]){ for(int i=0;i<n;i++) ans+=str[cur],cur^=1; return ans; } int tot=0,cnt=0; for(int i=n-1;i>0;i--){ if(x[i]){ if(x[i]<tot) return ""; int del=x[i]-tot; if(del) cur^=1; cnt+=del; tot+=del; while(del){ for(int j=0;j<=i;j++) ans+=str[cur]; del--; if(del) ans+=str[cur^1]; } } // cout<<ans<<endl; tot+=cnt; } while(ans.length()<n){ cur^=1; ans+=str[cur]; } if(ans.length()>n) return ""; return ans; } };
第三题
题目大意
给定一棵无根树,如果一棵子树的直径是唯一的,那么这就是一个“nice”的子树。可以把子树理解为一个联通子图。
问有多少种取法,对1000000007取模。
待补。。。
upd at 2016.08.05
终于A掉了这题。
可以先枚举一条路径,强制它是唯一的直径,然后可以找到这条直径的中心,即子树的中心。
如果路径是奇数长度,那么中心有两个,否则只有一个。
然后进行树形dp。
由于直径是唯一的,所以就是从中心出发找到所有长度小于直径一半的取法。
对于一个点,如果它不在强制要求的直径上,那么它可以直接被删掉,那么它的子树也不会被取。
然后可以把它的儿子的状态可以全部收集上来,这里就是乘法原理。
具体看代码,代码说的比我好。
#include <vector> #include <map> #include <set> #include <queue> #include <deque> #include <stack> #include <bitset> #include <algorithm> #include <ctime> #include <numeric> #include <utility> #include <set> #include <map> #include <vector> #include <cstdio> #include <string> #include <cstring> #include <iostream> #include <algorithm> #define fi first #define se second #define pb push_back #define pq priority_queue #define lowbit(x) ((x)&-(x)) #define debug(x) cout<<#x<<' '<<x<<endl; #define rep(i,a,n) for(int i=a,_n=n;i<_n;++i) #define per(i,a,n) for(int i=(n)-1,_a=a;i>=_a;--i) #define travel(A,a,b) {rep(wefw,0,40)cout<<"*";cout<<endl;for(int werw=a;werw<=b;werw++)cout<<#A<<'['<<werw<<"] = "<<A[werw]<<endl;cout<<endl;} using namespace std; const int M=305; const int mod=1000000007; const int INF=0x7fffffff; typedef long long ll; typedef unsigned uint; typedef unsigned long long ull; typedef pair<int,int> pii; typedef pair<ll,ll> pll; inline int fast_pow(int x,int b,int MOD=mod){ int res=1; for(;b;b>>=1,x=x*1LL*x%MOD) if(b&1) res=res*1LL*x%MOD; return res; } int etot=0; class BearUniqueDiameter { public: int dis[M][M]; vector<int>edge[M]; ll rec(int x,int f,int l,int u,int v){ if(l<0) return 1; int not_in_chain=(dis[x][u]+dis[x][v]!=dis[u][v]); ll res=1; rep(i,0,edge[x].size()){ int to=edge[x][i]; if(to==f) continue; res=(res*rec(to,x,l-1,u,v))%mod; } return (res+not_in_chain)%mod; } int countSubtrees(vector <int> a, vector <int> b) { int n=a.size()+1; rep(i,0,n) rep(j,0,n) dis[i][j]=(i==j?0:20000); rep(i,0,n-1){ dis[a[i]][b[i]]=dis[b[i]][a[i]]=1; edge[a[i]].push_back(b[i]); edge[b[i]].push_back(a[i]); } rep(k,0,n)rep(i,0,n)rep(j,0,n) dis[i][j]=min(dis[i][k]+dis[k][j],dis[i][j]); int ans=n; rep(i,0,n){ rep(j,0,i){ int d=dis[i][j],u=-1,v=-1; rep(k,0,n){ if((d&1)&&dis[i][k]==d/2&&dis[j][k]==d/2+1) u=k; if((d&1)&&dis[i][k]==d/2+1&&dis[j][k]==d/2) v=k; if(!(d&1)&&dis[i][k]==d/2&&dis[j][k]==d/2) u=k; } if(~v) ans=(ans+rec(u,v,d/2-1,i,j)*rec(v,u,d/2-1,i,j))%mod; else ans=(ans+rec(u,-1,d/2-1,i,j))%mod; } } return ans; } };
相关文章推荐
- 概率最大骰子总和 Topcoder SRM 536 DIV1 第2题
- TopCoder SRM 569 DIV2 Level3: MegaFactorialDiv2
- Topcoder SRM Div2 Level2
- Topcoder SRM 547 DIV1 Level 1: Pillars
- TopCoder SRM DIV2 Level 3: RelativelyPrimeSubset
- TopCoder SRM 558 DIV2 Level 3:CatAndRabbit
- SRM 7.03 新功能
- Topcoder SRM642 TaroCutting
- topcoder arena 插件配置
- Convert from char to int OR Convert from int to char
- Topcoder Open 2014 Algorithm Round 1A
- TopCoder SRM 593: MayTheBestPetWin 势均力敌的赛跑
- TopCoder SRM 610: The Matrix 区分现实与梦境的棋盘
- Topcoder/SRM565
- TOPCODER/SRM565 DIVII 250、500pt(500pt无递归解法)
- TOPCODER/SRM 566 DIVII(250、500、1000题)(1000PT暂未附上代码)
- TOPCODE/SRM567 DIVII 250、500PT
- [题解]SRM 703 (Div.2)
- topcoder客户端下载地址
- SRM147_DIV2