Codeforces Round #130 (Div. 2)

来源:互联网 发布:软件项目付款比例 编辑:程序博客网 时间:2024/05/23 11:38

转载请注明出处,谢谢 http://blog.csdn.net/ACM_cxlove?viewmode=contents           by---cxlove

偶尔找场CF做做。

http://codeforces.com/contest/208

A. Dubstep

单词之间用若干个”WUB“隔开了,现在恢复原来的句子,字符串基本处理。

每次判断3位是否是指定字符串,注意转移时候指针的变化。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#define LL long long#define N 1000000using namespace std;char str[205];bool check(int i){if(str[i]=='W'&&str[i+1]=='U'&&str[i+2]=='B')return true;    return false;}int main(){while(scanf("%s",str)!=EOF){bool word=false;for(int i=0;i<strlen(str);i++){//如果不是“WUB”,说明接下来是单词if(!check(i)){if(word)printf(" ");for(;i<strlen(str);i++)//直到出现“WUB”单词结束if(check(i))break;elseprintf("%c",str[i]);i+=2;word=true;}elsei+=2;}puts("");}return 0;}

B. Solitaire

有N堆牌,每次可以把最右边的往倒数第二堆上放,或者放到倒数第四堆,其中要求是最上面一张的花色或者面值一样。

直接记忆化搜索,map保存已搜到的状态。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<string>#include<map>#define LL long long#define N 1000000using namespace std;map<vector<string>,bool>m;int n;bool check(string s1,string s2){if(s1[0]==s2[0])return true;if(s1[1]==s2[1])return true;return false;}bool dfs(vector<string>s){if(s.size()<=1)return true;if(m.count(s))return m[s];m[s]=false;if(s.size()>=4&&check(s[s.size()-1],s[s.size()-1-3])){vector<string>ts=s;ts[s.size()-1-3]=s[s.size()-1];ts.pop_back();if(dfs(ts))m[s]=true;}if(s.size()>=2&&check(s[s.size()-1],s[s.size()-1-1])){vector<string>ts=s;ts[s.size()-1-1]=s[s.size()-1];ts.pop_back();if(dfs(ts))m[s]=true;}return m[s];}vector<string>s;int main(){while(scanf("%d",&n)!=EOF){s.clear();m.clear();for(int i=0;i<n;i++){string str;cin>>str;s.push_back(str);}cout<<(dfs(s)?"YES":"NO")<<endl;}return 0;}

C. Police Station

图论,软肋啊。

从1-N的最短路,求出某个点,在所有最短路径的最大点覆盖???解释不清楚。。。

总之先用floyd求出最短路,然后通过 DP,求出从1到i最短路有多少条以及从j到n的最短路有多少条。

然后枚举每一条边,从1到i+从j到n+1是从1到n的最短路,以及i到j为1,说明从i到j是最短路的路径。然后把i,j权值计算。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<string>#include<map>#define LL long long#define N 1000000#define inf 1<<20using namespace std;int n,m,dist[205][205];double cnt1[205],cnt2[205];int main(){while(scanf("%d%d",&n,&m)!=EOF){for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)dist[i][j]=i==j?0:inf;while(m--){int u,v;scanf("%d%d",&u,&v);dist[u][v]=1;dist[v][u]=1;}for(int k=1;k<=n;k++)for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);memset(cnt1,0,sizeof(cnt1));memset(cnt2,0,sizeof(cnt2));cnt1[1]=1;cnt2[n]=1;for(int d=1;d<=n;d++){for(int i=1;i<=n;i++)if(dist[1][i]==d)for(int j=1;j<=n;j++)if(dist[1][j]==d-1&&dist[j][i]==1)cnt1[i]+=cnt1[j];for(int i=1;i<=n;i++)if(dist[n][i]==d)for(int j=1;j<=n;j++)if(dist[n][j]==d-1&&dist[j][i]==1)cnt2[i]+=cnt2[j];}double num[205];memset(num,0,sizeof(num));for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)if(dist[1][i]+dist[j][n]+1==dist[1][n]&&dist[i][j]==1){num[i]+=cnt1[i]*cnt2[j];num[j]+=cnt2[j]*cnt1[i];}double mmax=0.0;for(int i=1;i<=n;i++)mmax=max(mmax,num[i]);printf("%.10f\n",mmax/cnt1[n]);}return 0;}


D. Prizes, Prizes, more Prizes

直接模拟,每次吃一块,然后从代价最高的物品开始取,取的时候不能模拟,直接计算就行了。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#define LL long long#define N 1000000using namespace std;struct Node{int cost,idx;}a[5];int n;LL p[50];bool cmp(Node n1,Node n2){return n1.cost>n2.cost;}int main(){while(scanf("%d",&n)!=EOF){for(int i=0;i<n;i++)scanf("%I64d",&p[i]);LL sum=0;for(int i=0;i<5;i++){scanf("%d",&a[i].cost);a[i].idx=i;}sort(a,a+5,cmp);LL cnt[5];memset(cnt,0,sizeof(cnt));for(int i=0;i<n;i++){sum+=p[i];for(int j=0;j<5;j++){cnt[a[j].idx]+=sum/a[j].cost;sum%=a[j].cost;}}printf("%I64d %I64d %I64d %I64d %I64d\n%I64d\n",cnt[0],cnt[1],cnt[2],cnt[3],cnt[4],sum);}return 0;}