您的位置:首页 > 运维架构

人生第一场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