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;
}
本文探讨了如何通过改进算法和数据结构实现高效的数据处理。包括排序算法优化、动态规划应用、哈希算法效率提升、贪心算法策略、深度优先搜索优化等。同时,文章还涉及了数据结构如二叉树、队列、栈、数组、链表、B树、散列表的应用与优化。旨在提高程序执行速度与资源利用效率。
1348

被折叠的 条评论
为什么被折叠?



