The Closest Fibonacci Number
The Fibonacci sequence Fn is defined by Fn+2=Fn+1+Fn for n≥0, with F0=0 and F1=1. The closest Fibonacci number is defined as the Fibonacci number with the smallest absolute difference with the given integer N.
Your job is to find the closest Fibonacci number for any given N.
Input Specification:
Each input file contains one test case, which gives a positive integer N (≤10^8).
Output Specification:
For each case, print the closest Fibonacci number. If the solution is not unique, output the smallest one.
Sample Input:
305
Sample Output:
233
Hint:
Since part of the sequence is { 0, 1, 1, 2, 3, 5, 8, 12, 21, 34, 55, 89, 144, 233, 377, 610, ... }, there are two solutions: 233 and 377, both have the smallest distance 72 to 305. The smaller one must be printed out.
题意:输入一个n,输出离他最相近的斐波那契数。
解析:因为n的范围在1e8之内,我们直接暴力遍历一定范围内的斐波那契数与答案取min即可。
#include <bits/stdc++.h>
using namespace std;
const int N=1e3+5;
int a[N];
void solve()
{int n,mi,ans=1;scanf("%d",&n);a[1]=a[2]=1;mi=n-1;//初始最小距离直接取跟1for(int i=3;;i++){a[i]=a[i-1]+a[i-2];if(abs(n-a[i])<mi) mi=abs(n-a[i]),ans=a[i];//更新即可if(a[i]>1e9) break;//如果大于1e9,那么最近数肯定已经取到了}printf("%d\n",ans);
}
int main()
{int t=1;//scanf("%d",&t);while(t--) solve();return 0;
}
Subsequence in Substring
A substring is a continuous part of a string. A subsequence is the part of a string that might be continuous or not but the order of the elements is maintained. For example, given the string atpaaabpabtt
, pabt
is a substring, while pat
is a subsequence.
Now given a string S and a subsequence P, you are supposed to find the shortest substring of S that contains P. If such a solution is not unique, output the left most one.
Input Specification:
Each input file contains one test case which consists of two lines. The first line contains S and the second line P. S is non-empty and consists of no more than 104 lower English letters. P is guaranteed to be a non-empty subsequence of S.
Output Specification:
For each case, print the shortest substring of S that contains P. If such a solution is not unique, output the left most one.
Sample Input:
atpaaabpabttpcat
pat
Sample Output:
pabt
题意:给两个字符串a b,要求你在a中找出一段子串的子序列是b,输出满足条件的最短且最左的子串。
解法一:不懂,居然直接暴力匹配就行了,而且还跑的比"优化的"还快。。
#include <bits/stdc++.h>
using namespace std;
const int N=1e4+5;
void solve()
{string a,b,ans;cin>>a>>b;int ans_len=1e9;//答案字符串长度for(int i=0;i<a.size();i++){if(a[i]!=b[0]) continue;string x;for(int j=i,k=0;j<a.size();j++){if(a[j]==b[k]) k++;x+=a[j];if(k==b.size())//匹配完成{if(j-i+1<ans_len) ans_len=j-i+1,ans=x;//更新break;}}}cout<<ans<<"\n";
}
int main()
{int t=1;//scanf("%d",&t);while(t--) solve();return 0;
}
解法二:建一个pos[N][30]来记录第i位开始往后某个字母最近的位置,pos数组可以从后往前遍历建造,复杂度是O(N*26),然后匹配时候就可以跳着进行,复杂度卡线,抖动过题😥
#include <bits/stdc++.h>
using namespace std;
const int N=1e4+5;
char a[N],b[N];
int pos[N][30];
void solve()
{scanf("%s%s",a+1,b+1);int n=strlen(a+1),m=strlen(b+1);for(int i=n;i>=1;i--)//记录第i位开始往后某个字母最近的位置{for(int j=1;j<=26;j++) pos[i][j]=pos[i+1][j];pos[i][a[i]-'a'+1]=i;}int ans_len=1e9,ansl=-1,ansr=-1;for(int i=1;i<=n;i++){if(a[i]==b[1]){int l=i,r=i,k=2;while(pos[r+1][b[k]-'a'+1]!=0&&k<=m)//注意要从r+1开始,避免相同字母导致原地跳{r=pos[r+1][b[k]-'a'+1];if(r-l+1>=ans_len) break;//剪枝..k++;}if(k==m+1&&r-l+1<ans_len) ans_len=r-l+1,ansl=l,ansr=r;}}for(int i=ansl;i<=ansr;i++) printf("%c",a[i]);printf("\n");
}
int main()
{int t=1;//scanf("%d",&t);while(t--) solve();return 0;
}
File Path
The figure shows the tree view of directories in Windows File Explorer. When a file is selected, there is a file path shown in the above navigation bar. Now given a tree view of directories, your job is to print the file path for any selected file.
Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤103), which is the total number of directories and files. Then N lines follow, each gives the unique 4-digit ID of a file or a directory, starting from the unique root ID 0000
. The format is that the files of depth d will have their IDs indented by d spaces. It is guaranteed that there is no conflict in this tree structure.
Then a positive integer K (≤100) is given, followed by K queries of IDs.
Output Specification:
For each queried ID
, print in a line the corresponding path from the root to the file in the format: 0000->ID1->ID2->...->ID
. If the ID
is not in the tree, print Error: ID is not found.
instead.
Sample Input:
14
00001234223432344234423523335234623472349999000182340002
4 9999 8234 0002 6666
Sample Output:
0000->1234->2234->6234->7234->9999
0000->1234->0001->8234
0000->0002
Error: 6666 is not found.
题意:如图所示,给n个文件,空格的个数就是深度,有q个询问,要求输出该文件的路径或者报告不存在。
解析: 空格的个数其实就是文件的深度,而一个文件的父亲一定在它的上方,数据较小,直接往上不断寻找深度比自身小1的就是父亲文件。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+5;
string str[N];
map<string,int> dep;//记录每个文件夹的"深度"
map<string,string> fa;//记录该文件夹归属哪个文件
void solve()
{int n;scanf("%d",&n);getchar();//下方要getline,需要吃掉scanf的回车for(int i=1;i<=n;i++){string name;getline(cin,str[i]);int cnt=0;for(int j=0;j<str[i].size();j++){if(str[i][j]==' ') cnt++;//空格个数就是深度else name+=str[i][j];}dep[name]=cnt;str[i]=name;if(name=="0000") continue;for(int j=i-1;j>=1;j--)//直接从此往上暴力寻找父亲{if(dep[str[j]]==cnt-1){fa[name]=str[j];break;}}}int q;scanf("%d",&q);fa["0000"]="0000";//根目录父亲是本身while(q--){string x;cin>>x;if(fa[x]=="")//找不到{printf("Error: ");cout<<x;printf(" is not found.\n");continue;}vector<string> path;//答案路径while(x!="0000") path.push_back(x),x=fa[x];path.push_back("0000");reverse(path.begin(), path.end());for(int i=0;i<path.size();i++){if(i!=0) printf("->");cout<<path[i];}printf("\n");}
}
int main()
{int t=1;//scanf("%d",&t);while(t--) solve();return 0;
}
Chemical Equation
A chemical equation is the symbolic representation of a chemical reaction in the form of symbols and formulae, wherein the reactant entities are given on the left-hand side and the product entities on the right-hand side. For example, CH4+2O2=CO2+2H2O means that the reactants in this chemical reaction are methane and oxygen: CH4 and O2, and the products of this reaction are carbon dioxide and water: CO2 and H2O.
Given a set of reactants and products, you are supposed to tell that in which way we can obtain these products, provided that each reactant can be used only once. For the sake of simplicity, we will consider all the entities on the right-hand side of the equation as one single product.
Input Specification:
Each input file contains one test case. For each case, the first line gives an integer N (2≤N≤20), followed by N distinct indices of reactants. The second line gives an integer M (1≤M≤10), followed by M distinct indices of products. The index of an entity is a 2-digit number.
Then a positive integer K (≤50) is given, followed by K lines of equations, in the format:
reactant_1 + reactant_2 + ... + reactant_n -> product
where all the reactants are distinct and are in increasing order of their indices.
Note: It is guaranteed that
- one set of reactants will not produce two or more different products, i.e. situation like
01 + 02 -> 03
and01 + 02 -> 04
is impossible; - a reactant cannot be its product unless it is the only one on the left-hand side, i.e.
01 -> 01
is always true (no matter the equation is given or not), but01 + 02 -> 01
is impossible; and - there are never more than 5 different ways of obtaining a product given in the equations list.
Output Specification:
For each case, print the equations that use the given reactants to obtain all the given products. Note that each reactant can be used only once.
Each equation occupies a line, in the same format as we see in the inputs. The equations must be print in the same order as the products given in the input. For each product in order, if the solution is not unique, always print the one with the smallest sequence of reactants -- A sequence { a1,⋯,am } is said to be smaller than another sequence { b1,⋯,bn } if there exists 1≤i≤min(m,n) so that aj=bj for all j<i, and ai<bi.
It is guaranteed that at least one solution exists.
Sample Input:
8 09 05 03 04 02 01 16 10
3 08 03 04
6
03 + 09 -> 08
02 + 08 -> 04
02 + 04 -> 03
01 + 05 -> 03
01 + 09 + 16 -> 03
02 + 03 + 05 -> 08
Sample Output:
02 + 03 + 05 -> 08
01 + 09 + 16 -> 03
04 -> 04
题意:给定n个反应物,m个要求生成物,k个反应方程式,自身可以直接等于反应物,每个反应物只能用一次,要求输出能够生产所有给定生成物的方程式,如果多条满足,输出参数最小的。
解析:数据小,DFS暴力每个方案,用map存下当前合成物所有的方程式,DFS前可以直接将生成物的所有方程式排序,这样DFS找到的第一个可行方案就是答案。
#include <bits/stdc++.h>
using namespace std;
const int N=1e2+5;
int n,m,k;
map<int,vector<vector<int>>> mp;
int has[N],a[N],ans_id[N];//分别记录是否存在该物质以及要求合成的物质
bool find_ans;
void dfs(int cnt)
{if(find_ans) return;if(cnt==m+1){find_ans=true;for(int i=1;i<=m;i++){int vl=a[i],id=ans_id[vl];vector<int> v=mp[vl][id];for(int j=0;j<v.size();j++){if(j!=0) printf(" + ");printf("%02d",v[j]);}printf(" -> %02d\n",vl);}return;}int vl=a[cnt];//当前需要合成的物质for(int i=0;i<mp[vl].size();i++){vector<int> v=mp[vl][i];bool ok=true;//判断当前所需物质是否还有for(int j=0;j<v.size();j++){if(!has[v[j]]){ok=false;break;}}if(ok)//余料充足{for(int j=0;j<v.size();j++) has[v[j]]--;//使用这些物质ans_id[vl]=i;//物质vl使用第i个方案dfs(cnt+1);for(int j=0;j<v.size();j++) has[v[j]]++;//回溯}}
}
void solve()
{scanf("%d",&n);for(int i=1;i<=n;i++){int x;scanf("%d",&x);has[x]++;}scanf("%d",&m);for(int i=1;i<=m;i++) scanf("%d",&a[i]);scanf("%d",&k);getchar();//因为下面要getline,因此要吃掉scanf最后一个回车for(int i=1;i<=k;i++){string s;getline(cin,s);int sum=0;vector<int> v;for(int j=0;j<s.size();j++){if(s[j]==' '||s[j]=='-') continue;if(s[j]>='0'&&s[j]<='9') sum=sum*10+s[j]-'0';else v.push_back(sum),sum=0;}mp[sum].push_back(v);}for(int i=1;i<=m;i++){int vl=a[i];if(has[vl]) mp[vl].push_back({vl});//自身等于合成物sort(mp[vl].begin(),mp[vl].end());//每个合成物内部排序}dfs(1);
}
int main()
{int t=1;//scanf("%d",&t);while(t--) solve();return 0;
}