人生第一场SRM SRM695 Div.2

来源:互联网 发布:速达 sqlserver未安装 编辑:程序博客网 时间:2024/06/06 00:15

第一题

模拟题,用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;    }};
0 0
原创粉丝点击