具体的操作方法:
题目 埃及分数
将一个分数 a/b,分解成若干个单位分数1/x的和,要求找到加数个数最少且最小的单位分数最大的方案。
#include
using namespace std;
typedef long long ll;
int ans[105],vis[105],maxed;
ll gcd(ll a,ll b)//求a和b的公约数
{
return b?gcd(b,a%b):a;
}
ll get_first(ll a, ll b)
{
//确定一个分母,1/c是最贴近并小于a/b的
ll c=b/a;
if(b%a)
c++;
return c;
}
bool better(int d)
{
for(int i=d;i>=1;i--)
{
if(vis[i]!=ans[i])
{
return ans[i]==0||vis[i]<ans[i];
}
}
return false;
}
bool dfs(int step,int c,ll a,ll b)
{
//step代表dfs搜索的第几层
if(step==maxed)
{
if(b%a)
return false;
vis[step]=b/a;//得到分母并标记好
if(better(step))
{
//保证加数不重复
memcpy(ans,vis,sizeof(vis));
}
return true;
}
c=max((ll)c,get_first(a,b));
bool sign=false;
for(int i=c;;i++)
{
if(b*(maxed-step+1)<=i*a)
break;
vis[step]=i;//存分母
ll b2=b*i;//a2和b2是减去此时得到的分数1/i后得到的新的分子和分母
ll a2=a*i-b;
ll k=gcd(a2,b2);//得到公约数
if(dfs(step+1,i+1,a2/k,b2/k))
sign=true;
}
return sign;
}
int main()
{
ll a,b;
scanf("%lld%lld",&a,&b);//a是分子,b是分母
for(maxed=1;;maxed++)
{
if(dfs(1,get_first(a,b),a,b))
{
break;
}
}
printf("%lld/%lld=1/%d",a,b,ans[1]);
for(int i=2;i<=maxed;i++)
printf("+1/%d",ans[i]);
return 0;
}
题目 DNA sequence
The twenty-first century is a biology-technology developing century. We know that a gene is made of DNA. The nucleotide bases from which DNA is built are A(adenine), C(cytosine), G(guanine), and T(thymine). Finding the longest common subsequence between DNA/Protein sequences is one of the basic problems in modern computational molecular biology. But this problem is a little different. Given several DNA sequences, you are asked to make a shortest sequence from them so that each of the given sequence is the subsequence of it.
For example, given “ACGT”,“ATGC”,“CGTT” and “CAGT”, you can make a sequence in the following way. It is the shortest but may be not the only one.
Input
The first line is the test case number t. Then t test cases follow. In each case, the first line is an integer n ( 1<=n<=8 ) represents number of the DNA sequences. The following k lines contain the k sequences, one per line. Assuming that the length of any sequence is between 1 and 5.
Output
For each test case, print a line containing the length of the shortest sequence that can be made from these sequences.
Sample Input
1
4
ACGT
ATGC
CGTT
CAGT
Sample Output
8
#include
#include
#include
#include
using namespace std;
int T,n,vis[10],sizee;//sizee为构造的DNA的最短长度,vis[i]表示第i个序列正在占用的位置
char c[10]="ACTG";
struct node{
char s[10];
int len;
};
node a[10];
int length()//还需要几个位置
{
int ans=0;
for(int i=0;i<n;i++)
{
ans=max(ans,a[i].len-vis[i]);
}
return ans;
}
int dfs(int b)//b代表当前长度
{
if(b+length()>sizee)
return 0;
if(length()==0)
return 1;
int pos[10];
for(int i=0;i<4;i++)
{
int sign=0;
for(int j=0;j<n;j++)
pos[j]=vis[j];
for(int j=0;j<n;j++)
{
if(a[j].s[vis[j]]==c[i])
{
sign=1;
vis[j]++;
}
}
if(sign)
{
if(dfs(b+1))
{
return 1;
}
for(int j=0;j<n;j++)//否则
{
vis[j]=pos[j];
}
}
}
return 0;
}
int main()
{
scanf("%d",&T);
while(T--){
sizee=0;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
cin>>a[i].s;
a[i].len=strlen(a[i].s);
sizee=max(sizee,a[i].len);
vis[i]=0;
}
while(1)
{
if(dfs(0))
break;
sizee++;
}
cout<<sizee<<endl;
}
return 0;
}