C.阶乘约数
解题思路
1.根据数学公式:
任意一个正整数 X 都可以表示成若干个质数乘积的形式,即 X = p1^α1 ∗ p2@α2 …… ∗ pk^αk
约数个数 = (a1 + 1)(a2 + 1)……(ak + 1)
2.用p[i]表示n中的素数约数i的a1次幂;
代码展示
#include<bits/stdc++.h>
using namespace std;
int p[200];//p
void init(){
for(int i=2;i<=100;i++){
int n=i;
for(int j=2;j<=n/j;j++){//保证得到的结果是质数,因为 2~n/j都无法整除
while(n%j==0){
n/=j;
p[j]+=1;
}
}
if(n>1)p[n]+=1;
}
}
int main(){
init();
long long ans=1;
for(int i=2;i<=100;i++){
if(p[i])ans*=(p[i]+1);
cout<<ans<<endl;
}
cout<<ans<<endl;
return 0;
}
总结
1.就是一个数学公式;
2.其实做题的时候并非毫无头绪,也想到肯定会与质因数有关,但不了解具体关系~~~
D.本质上升序列
解题思路
1.由于字符串有200位,DFS遍历不可行;
2.用dp处理,与LIS类似,num[i]记录以s[i]结尾的递增子串个数;
3.在LIS中,当s[i]>s[j]使,num[i]=max(num[i],num[j]+1)是为了求出最长的子串;类比可得动态规划方程 num[i]+=num[j];
4.当s[i]==s[j]时,num[i]-=num[j],下面画图解释;
(图待完善~~~)
代码展示
#include<bits/stdc++.h>
using namespace std;
/*
*/
string s;
int num[100];//以i结尾的递增子串个数
int main(){
string s;
cin>>s;
int l=s.size();
int ans=0;
for(int i=0;i<l;i++){
num[i]=1;
for(int j=0;j<i;j++){
if(s[i]>s[j])
num[i]+=num[j];
else if(s[i]==s[j])
num[i]-=num[j];
//!!!
}
ans+=num[i];
// cout<<"num[] = "<<num[i]<<endl;
}
cout<<ans<<endl;
return 0;
}
E.玩具蛇
解题思路
1.玩具蛇的起点A可以在1~16的任何一个位置;
2.从A所处的(x,y)出发,暴力搜素A~P的位置即可,因为A的位置不一样,所以不会重复;
代码展示
F.皮亚诺曲线
解题思路
代码展示
H.答疑
解题思路
假设排序之后的每人的si,ai,ei;
那么就有每人答疑时间为:
1 s1+a1
2 s1+a1+e1 + s2+a2
3 s1+a1+e1 + s2+a2+e2 + s3+a3
4 ~~~~~
n ~~~~~
那么不难看出,前面的学生的用时总和出现次数很多,所以我们只要保证前面的学生的总用时尽可能小,那么总答疑时间就最小。
代码展示
就不展示了,简单的结构体排序~~
J.质数行者
解题思路
1.题目很简单,就是简单的搜索;
2.用BFS从(1,1,1)开始遍历,记录队列中(5,6,1)出现的次数,即为路径数
3.因为始终是向南、东、上走,不会回去,所以不需要判断节点是否访问。
代码展示
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
/*
思路:
5 6 1
3 4 1 1 2 1
*/
struct node{
int x,y,z;
};
bool G[1005][1005][1005];
bool Prim(int x){
if(x<2)return false;
for(int i=2;i*i<=x;i++){
if(x%i==0)return false;
}
return true;
}
vector<int>prim;
int maxp;
void init(){
for(int i=2;i<=maxp;i++){
if(Prim(i))prim.push_back(i);
}
}
int n,m,k;
ll BFS(){
ll ans=0;
queue<node>q;
node temp;
temp.x=1,temp.y=1,temp.z=1;
q.push(temp);
while(!q.empty()){
temp=q.front();
q.pop();
if(temp.x==n&&temp.y==m&&temp.z==k){
ans+=1;
ans=ans%1000000007;
continue;
}
for(int i=0;i<3;i++){
for(int j=0;j<prim.size();j++){
bool flag=0;
node f;
f.x=temp.x;f.y=temp.y;f.z=temp.z;
if(i==0&&temp.x+prim[j]<=n){//x
f.x=temp.x+prim[j];
flag=1;
}
else if(i==1&&temp.y+prim[j]<=m){//y
f.y=temp.y+prim[j];
flag=1;
}
else if(i==2&&temp.z+prim[j]<=k){//y
f.z=temp.z+prim[j];
flag=1;
}
if(!G[f.x][f.y][f.z]&&flag){
q.push(f);
//cout<<f.x<<" "<<f.y<<" "<<f.z<<" "<<ans<<endl;
}
}
}
}
return ans;
}
int main(){
cin>>n>>m>>k;
maxp=max(max(n,m),k);
init();
for(int i=0;i<2;i++){
int a,b,c;
cin>>a>>b>>c;
G[a][b][c]=1;
}
ll ans=BFS();
cout<<ans<<endl;
return 0;
}