topcoder乱作系列2 srm503 srm504
2016-09-07 09:53
483 查看
srm 503 250pts
注意到答案只能是-1或1或2,判一下就行了。#include <bits/stdc++.h> using namespace std; class ToastXToast { public: int bake(vector<int>a1,vector<int>a2) { sort(a1.begin(),a1.end()); sort(a2.begin(),a2.end()); if(a1[0]>a2[0])return -1; if(a1.back()>a2.back())return -1; if(a1.back()<a2[0])return 1; return 2; } };
srm 503 500pts
考虑每个v点的贡献,将所有v点和c点按到当前v点的距离排序,按距离枚举所有的点,如果枚举到一个c点那么之后的所有点都没有用了,所以计算当前c点后退出。枚举的每个点的贡献为 距离*概率,距离随便算,只考虑概率就行了。
设当前点之前共有x个点。
如果当前枚举的是一个v点那么概率为1(x+1)(x+2)
否则概率为1x+1
#include <bits/stdc++.h> using namespace std; #define ld long double #define ll long long int n,m; struct poi { int x,y,pos; poi(){} poi(int x,int y,int pos):x(x),y(y),pos(pos){} }now,c[52],v[52]; double bir[110],ans; ll sq(int x){return (ll)x*x;} ll dis(poi p1,poi p2) {return sq(p1.x-p2.x)+sq(p1.y-p2.y);} int cmp(poi p1,poi p2) {return dis(p1,now)<dis(p2,now);} int cmp1(poi p1,poi p2) {return p1.pos<p2.pos;} class KingdomXCitiesandVillages { public: double determineLength(vector<int>cx,vector<int>cy,vector<int>vx,vector<int>vy) { n=cx.size();m=vx.size(); for(int i=0;i<n;i++) c[i+1]=poi(cx[i],cy[i],i+1); for(int i=0;i<m;i++) v[i+1]=poi(vx[i],vy[i],i+1); for(int i=1;i<=m;i++) { now=v[i]; sort(c+1,c+1+n,cmp); sort(v+1,v+1+m,cmp); for(int j=2;j<=m+1;j++) { if(j==m+1||dis(v[1],c[1])<=dis(v[1],v[j])) { ans+=sqrt((ld)dis(v[1],c[1]))/(j-1); break; } ans+=sqrt((ld)dis(v[1],v[j]))/(j-1)/j; } sort(v+1,v+1+m,cmp1); } return ans; } }tmp;
srm 503 1000pts
看jry博客时被吓得不轻,不过写完觉得还好吧,并没有太多细节。思路还是挺神的。。。每加一条边图被分成两个部分,分成的两个部分是独立的。因此可以记忆化搜索。
由于边必须加在已有边上,因此加完后整个图长这样:
然后把b块单独拎出来:
那么可以用5个变量存一块,其中h4 可以用其他四个变量表示。
因此状态总数是O(hw3) 级别的。
转移分两条红线和两条蓝线四种转移。
边界是当这块中没有加楼梯的点时返回0。
特殊情况是最上面没有封顶的块,注意到这样的块只有一个,然后分这两种转移:
记录两个布尔变量r1,r2 表示当前块是不是最上面一块以及当前块在左面还是在右面。
对于最下面的情况,由于第一步一定是从最下边的一个点发出一条边,因此可以枚举蓝线部分:
不过需要保证红色部分没有要连边的点。
这样就不需要考虑最下面的情况了。
#include <bits/stdc++.h> using namespace std; #define ll long long #define ull unsigned long long #define seed 23333333 ull p[21]; struct node { int h,h1,h2,h3,h4,r1,r2; ull val; void get() {val=h+h1*p[1]+h2*p[2]+h3*p[3]+h4*p[4]+r1*p[5]+r2*p[6];} friend bool operator < (const node &r1,const node &r2) {return r1.val<r2.val;} }; map<node,ll>ma; int a[2][210],b[21],w,H[2]; ll ans; ll cal(int h,int h1,int h2,int h3,int h4,int r1,int r2) { node tmp=(node){h,h1,h2,h3,h4,r1,r2}; tmp.get(); if(ma.count(tmp))return ma[tmp]; ll ret=1ll<<60; if(r2==0) { int t1=0,t2=0; for(int i=h1+2;i<=H[0];i+=2) if(a[0][i])t1=1; for(int i=h3+2;i<=H[1];i+=2) if(a[1][i])t2=1; if(!t1&&!t2)ret=0; else { for(int i=h2+1;i<=h3;i++) { int t=h1+(i-h2)*2; ret=min(ret,cal(h1,h2,i,t,t,0,1)+cal(0,t,i,h3,0,0,0)+b[t-i]); } for(int i=h2+1;i<=h1;i++) { int t=h3+(i-h2)*2; ret=min(ret,cal(h3,h2,i,t,t,1,1)+cal(0,h1,i,t,0,0,0)+b[t-i]); } } } else { int t1=0; for(int i=h+2;i<h4;i+=2) if(a[r1][i])t1=1; if(!t1)ret=0; else { int x=h2+h4-h3; for(int i=h+2;i<h4;i+=2) { int t=h1+(i-h)/2; ret=min(ret,cal(h,h1,t,i,i,r1,r2)+cal(i,t,h2,h3,h4,r1,r2)+b[i-t]); } for(int i=x;i<h2;i++) { int t=h3+i-h2; ret=min(ret,cal(h,h1,i,t,h4,r1,r2)+b[t-i]); } x=h2+h-h1; for(int i=h+2;i<h4;i+=2) { int t=h3-(h4-i)/2; ret=min(ret,cal(h,h1,h2,t,i,r1,r2)+cal(i,i,t,h3,h4,r1,r2)+b[t-i]); } for(int i=h2+1;i<=x;i++) { int t=i-h2+h1; ret=min(ret,cal(h,t,i,h3,h4,r1,r2)+b[i-t]); } } } ma[tmp]=ret; return ret; } void init() { p[0]=1; for(int i=1;i<=15;i++) p[i]=p[i-1]*seed; } class KingdomXEmergencyStaircase { public: ll determineCost(string s1,string s2,vector<int>vec) { init(); w=vec.size(); H[0]=s1.size()*2+w;H[1]=s2.size()*2+w; for(int i=0;i<s1.size();i++) a[0][(i+1)*2]=s1[i]=='Y' ? 1:0; for(int i=0;i<s2.size();i++) a[1][(i+1)*2]=s2[i]=='Y' ? 1:0; for(int i=0;i<w;i++)b[i+1]=vec[i]; ans=1ll<<60; ll t=cal(0,w,0,0,0,0,0); for(int i=0;i<=w;i+=2) { if(i==w) ans=min(ans,t+b[w]); else { int t1=(w-i)/2; ans=min(ans,cal(i,i,i+t1,w,w,0,1)+t+b[w]+b[t1]); } if(a[0][i])break; } t=cal(0,0,0,w,0,0,0); for(int i=0;i<=w;i+=2) { if(i==w) ans=min(ans,t+b[w]); else { int t1=(w-i)/2; ans=min(ans,cal(i,i,i+t1,w,w,1,1)+t+b[w]+b[t1]); } if(a[1][i])break; } return ans; } }tmp;
srm 504 250pts
按题意模拟一下就行了,记录一下变了几次色。#include <bits/stdc++.h> using namespace std; int a[110000]; class MathContest { public: int countBlack(string s,int tim) { int len=s.size(),now=0,pos=0,ans=0,head=1,tail=0; for(int i=0;i<len;i++) a[++tail]=s[i]=='B' ? 1:0; for(int i=2;i<=tim;i++) { for(int j=1;j<=len;j++) a[++tail]=a[j]; } while(tail>=head) { int t; if(pos)t=a[tail--]^now; else t=a[head++]^now; if(t==0)pos^=1; else now^=1; ans+=t; } return ans; } }tmp;
srm 504 500pts
第一行一定不变,枚举 1 到 n−1 行,模拟一下算出下一行每一个点的颜色。分没有颜色,黑,白,三种。如果有颜色,看和给出的颜色是否相符,相符答案乘2,否则答案为0。#include <bits/stdc++.h> using namespace std; #define mod 1000000007 #define ll long long int val[61]; int qpow(int x,int y) { int ret=1; while(y) { if(y&1)ret=(ll)ret*x%mod; x=(ll)x*x%mod;y>>=1; } return ret; } class AlgridTwo { public: int makeProgram(vector<string>s) { int n=s.size(),m=s[0].size(),ans=0; for(int i=0;i<n-1;i++) { memset(val,-1,sizeof(val)); for(int j=0;j<m-1;j++) { if(s[i][j]=='W'&&s[i][j+1]=='B') val[j]=val[j+1]=0; if(s[i][j]=='B'&&s[i][j+1]=='W') val[j]=val[j+1]=1; if(s[i][j]=='B'&&s[i][j+1]=='B') swap(val[j],val[j+1]); } for(int j=0;j<m;j++) if(val[j]!=-1) { if((s[i+1][j]=='B')!=val[j])return 0; ans++; } } return qpow(2,ans); } }cls;
相关文章推荐
- topcoder 乱作系列1 srm500 srm501 srm502
- TopCoder SRM 688
- Topcoder SRM 656 (Div.1) 250 RandomPancakeStack - 概率+记忆化搜索
- [TopCoder][SRM] SRM 562 DIV 2
- Topcoder--SRM144 div1
- topcoder srm 610 div1
- TopCoder SRM 657 Div2 Problem 1000 - PolynomialRemainder(数学)
- topcoder srm 615 div1
- TopCoder SRM 658 Div1 300 - OddEvenTree (树的性质 + 构造)
- topcoder SRM 622 DIV2 FibonacciDiv2
- topcoder-srm144-div
- TopCoder SRM 634 Div2 Problem 1000 - SpecialStrings
- Topcoder SRM 635 Div2 1000 (一种 O(n) 求一棵树中最长连续边 长度的方法)
- [TopCoder] SRM580, DIV1, 600p, Solution
- topcoder SRM 593 DIV2 WolfDelaymaster
- topcoder srm 610 div2 250
- topcoder SRM 666 DIV2 CollectingTokens 树形dp
- TopCoder - SRM521 div1 500 RangeSquaredSubsets
- Topcoder SRM 514div2 500point
- topcoder srm 696 div1 -3