SRM 622 div1
2014-05-29 16:33
225 查看
好久没写博客了,最近状况不太好,有些力不从心,不知道还能走多远,留给自己的时间不多了……正好今天打了场tc,就发个题解吧……
250 floyd+枚举
这个题大概的意思就是给出一个完全图,每个点要从这个点出发到所有其他的点,并且只沿最短路走,如果有多条,那么就随机走。问题是求所有有向边有可能使用的此时大于等于T的边权和。n比较小,可以先用floyd求下最短路,然后枚举一下起点和终点,然后枚举边,判断当前边是否在最短路中。
代码:
500 贪心
给出一棵树,要求去掉一些边,将树分成尽可能少的树,并且新的树是原来的树的子树,任意两点之间的距离小于MaxDis。第一题浪费了好多时间,导致这题没弄完,其实很简单,对于一个结点来说,我们首先去掉那些距离这个点的最大距离大于MaxDis的子树,然后对于所有的子树,排序后,贪心从大到小删,直到任意两个点子树之间没有大于MaxDis的两个结点。
代码:
900 记忆化搜索
给出两个数A,B,求区间[A,B]中的数转化为“斐波那契进制数”再转化为二进制数以后的异或和。把前几项值列出来大概就能看出来了,比如12(010101),第一个比它小的是斐波那契数是8(010000),它们之间的数的值恰好和(1~4)相对应,只是多了个最高位,那么用map记录一下值,然后计算一下就好了,由于每次会减掉一个斐波那契数,所以要访问的值不会很多。位数可能比较大,用了bitset,比较方便~
代码:
250 floyd+枚举
这个题大概的意思就是给出一个完全图,每个点要从这个点出发到所有其他的点,并且只沿最短路走,如果有多条,那么就随机走。问题是求所有有向边有可能使用的此时大于等于T的边权和。n比较小,可以先用floyd求下最短路,然后枚举一下起点和终点,然后枚举边,判断当前边是否在最短路中。
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<map> #include<queue> #include<stack> #include<cmath> #include<vector> #define inf 0x3f3f3f3f #define Inf 0x3FFFFFFFFFFFFFFFLL #define eps 1e-9 #define pi acos(-1.0) using namespace std; typedef long long ll; const int maxn=55; class BuildingRoutes { public: int g[maxn][maxn],used[maxn][maxn],n; int d[maxn][maxn]; bool inq[maxn]; void floyd() { for(int i=0;i<n;++i) for(int j=0;j<n;++j) d[i][j]=g[i][j]; for(int k=0;k<n;++k) for(int i=0;i<n;++i) for(int j=0;j<n;++j) d[i][j]=min(d[i][j],d[i][k]+d[k][j]); for(int s=0;s<n;++s) for(int t=0;t<n;++t) { if(s==t) continue; for(int i=0;i<n;++i) for(int j=0;j<n;++j) if(d[s][i]+g[i][j]+d[j][t]==d[s][t]) used[i][j]++; } } int build(vector <string> dist, int T) { n=dist.size(); for(int i=0;i<n;++i) for(int j=0;j<n;++j) g[i][j]=dist[i][j]-'0'; memset(used,0,sizeof(used)); floyd(); int ans=0; for(int i=0;i<n;++i) for(int j=0;j<n;++j) if(used[i][j]>=T) ans+=g[i][j]; return ans; } };
500 贪心
给出一棵树,要求去掉一些边,将树分成尽可能少的树,并且新的树是原来的树的子树,任意两点之间的距离小于MaxDis。第一题浪费了好多时间,导致这题没弄完,其实很简单,对于一个结点来说,我们首先去掉那些距离这个点的最大距离大于MaxDis的子树,然后对于所有的子树,排序后,贪心从大到小删,直到任意两个点子树之间没有大于MaxDis的两个结点。
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<map> #include<queue> #include<stack> #include<cmath> #include<vector> #define inf 0x3f3f3f3f #define Inf 0x3FFFFFFFFFFFFFFFLL #define eps 1e-9 #define pi acos(-1.0) using namespace std; typedef long long ll; const int maxn=55; class Ethernet { public: vector<pair<int,int> >g[maxn]; int maxd[maxn],val[maxn],n,mxd; void dfs(int u) { maxd[u]=0;val[u]=0; int cnt=0; vector<int>num; for(int i=0;i<(int)g[u].size();++i) { int v=g[u][i].first; dfs(v); val[u]+=val[v]; num.push_back(maxd[v]+g[u][i].second); } sort(num.begin(),num.end()); cnt=num.size(); while(cnt>0&&num[cnt-1]>mxd) val[u]++,cnt--; while(cnt>1&&num[cnt-1]+num[cnt-2]>mxd) val[u]++,cnt--; if(cnt) maxd[u]=num[cnt-1]; } int connect(vector <int> parent, vector <int> dist, int maxDist) { n=parent.size()+1; for(int i=0;i<n;++i) g[i].clear(); mxd=maxDist; for(int i=0;i<n-1;++i) { g[parent[i]].push_back(make_pair(i+1,dist[i])); } dfs(0); return val[0]+1; } };
900 记忆化搜索
给出两个数A,B,求区间[A,B]中的数转化为“斐波那契进制数”再转化为二进制数以后的异或和。把前几项值列出来大概就能看出来了,比如12(010101),第一个比它小的是斐波那契数是8(010000),它们之间的数的值恰好和(1~4)相对应,只是多了个最高位,那么用map记录一下值,然后计算一下就好了,由于每次会减掉一个斐波那契数,所以要访问的值不会很多。位数可能比较大,用了bitset,比较方便~
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<map> #include<queue> #include<stack> #include<cmath> #include<vector> #include<bitset> #define inf 0x3f3f3f3f #define Inf 0x3FFFFFFFFFFFFFFFLL #define eps 1e-9 #define pi acos(-1.0) using namespace std; typedef long long ll; typedef bitset<72> bt; const int mod=1000000007; class FibonacciXor { public: ll f[110]; map<ll,bt>mp; bt Xor(bt a,bt b) { bt c; for(int i=0;i<72;++i) c[i]=(a[i]!=b[i]); return c; } void Init() { f[0]=1;f[1]=2; for(int i=2;i<72;++i) f[i]=f[i-1]+f[i-2]; mp.clear(); } bt cal(ll x) { if(x==1) return bt(1); if(x==0) return bt(0); if(mp.find(x)!=mp.end()) return mp[x]; bt msk; int i=71; for(;i>=0;--i) { if(f[i]<=x) break; } if(x==f[i]) { msk[i]=1; return mp[x]=Xor(msk,cal(x-1)); } ll y=(x-f[i]); if(y&1) msk[i]=1; msk=Xor(msk,cal(y)); msk=Xor(msk,cal(f[i])); return mp[x]=msk; } int find(long long A, long long B) { Init(); bt res=Xor(cal(B),cal(A-1)); ll val=1,ans=0; for(int i=0;i<72;++i) { if(res.test(i)) ans=(ans+val)%mod; val=val*2%mod; } return (ans%mod+mod)%mod; } };
相关文章推荐
- SRM 622 div1 250
- topcoder SRM 622 DIV2 BoxesDiv2
- topcoder SRM 622 DIV2 FibonacciDiv2
- SRM 622 DIV 2
- 记第一次SRM (SRM489 div2)
- SRM 400 Div1
- [TC SRM 571] DIV1 1000
- 【解题报告】 SRM412_div1_250pt 和 SRM411_div2_900pt
- SRM 510 D2L3:TheLuckyBasesDivTwo,brute force,optimization
- SRM 502 DIV2 RP爆发
- Topcoder SRM 664 DIV 1
- SRM 565 div1
- TopCoder——SRM 519 DIV 2
- TOPCODER SRM 686 div2 1000
- topcoder srm 711 div1 -3
- TopCoder 250 points 9-SRM 148 DIV 1 75/250 30%
- topcoder srm 440 div1
- SRM 721 DIV2
- SRM 583 Div II Level One:SwappingDigits
- SRM 575 250 DIV2