Codeforces Round #290 (Div. 1) 解题报告(A B)

来源:互联网 发布:网络老虎机揭秘 编辑:程序博客网 时间:2024/05/01 08:34

A. Fox And Names


        有一些仅包含小写字母的字符串,问能不能给26个字母定义一个顺序,使得那些串是按字典序排列的。

        把每个字母作为图的一个顶点,对每两个串,找到它们第一个相异的字母,建边,跑拓扑排序。注意处理串前缀相同,但是长度不同的情况,长的串字典序靠后。

#include <iostream>  #include <stdio.h>  #include <string>  #include <map>  #include <vector>  #include <stack>  #include <queue>  #include <string.h>  #include <algorithm>  #include <math.h>    using namespace std;  string names[110];bool mat[30][30];int len[110];bool vis[30];stack<int> ans;void dfs(int u){vis[u]=1;for(int i=0;i<26;i++){if(mat[u][i]){if(!vis[i])dfs(i);}}ans.push(u);}int main(){int n;cin>>n;for(int i=1;i<=n;i++){cin>>names[i];len[i]=names[i].size();}bool ok=1;for(int i=1;i<=n;i++){for(int j=i+1;j<=n;j++){int sz=min(len[i],len[j]);int k=0;for(k=0;k<sz;k++){if(names[i][k]!=names[j][k])break;}if(k!=sz){mat[names[i][k]-'a'][names[j][k]-'a']=1;}else{if(len[i]>len[j])ok=0;}}}for(int k=0;k<26;k++){for(int i=0;i<26;i++){for(int j=0;j<26;j++){if(mat[i][k]&&mat[k][j]){mat[i][j]=1;}}}}for(int i=0;i<26;i++){for(int j=0;j<26;j++){if(mat[i][j]&&mat[j][i]){ok=0;}}}if(ok){for(int i=0;i<26;i++){if(!vis[i]){dfs(i);}}while(!ans.empty()){char ch=ans.top()+'a';ans.pop();cout<<ch;}}else{cout<<"Impossible"<<endl;}return 0;}

B. Fox And Jumping


        有一些卡片,卡片i长度为li,花费ci,买了以后就可以无限用。你需要用尽可能少的钱,使得那些li能互相加减凑出所有自然数。

        分析一下。。凑出所有自然数就是要凑出1,凑出1的条件是它们的最大公约数为1。那么我们就可以用dp来解决,dp(i)表示凑i的最小花费,对每张卡片去更新dp。因为花费的取值范围比较大,我开了两个map来解决,当然也可以哈希。

#include <iostream>  #include <stdio.h>  #include <string>  #include <map>  #include <vector>  #include <stack>  #include <queue>  #include <string.h>  #include <algorithm>  #include <math.h>    using namespace std;  int l[310];int c[310];map<int,int> mp;int gcd(int a, int b){ return a == 0 ? b : gcd(b % a, a); } int main(){int n;cin>>n;for(int i=1;i<=n;i++){cin>>l[i];}for(int i=1;i<=n;i++){cin>>c[i];}mp[0]=0;for(int i=1;i<=n;i++){map<int,int> tmp;map<int,int>::iterator it=mp.begin();for(;it!=mp.end();it++){int cmp=mp[it->first]+c[i];int pos=gcd(it->first,l[i]);if(mp.count(pos)==0||mp[pos]>cmp){if(tmp.count(pos)&&tmp[pos]<cmp)continue;tmp[pos]=cmp;}}//it=tmp.begin();for(;it!=tmp.end();it++){mp[it->first]=it->second;}}if(mp[1]!=0){cout<<mp[1]<<endl;}else{cout<<"-1"<<endl;}return 0;}





0 0
原创粉丝点击