8月1日解题报告
来源:互联网 发布:阿里云200m无限流量 编辑:程序博客网 时间:2024/05/16 00:35
hdu 1164
输入一个数,要求输出所有因子乘积的形式,并从小到大排列,数字与数字之间用“*”隔开,解决这类问题不需要素数打表,只需要用唯一分解定理即可。
#include<iostream>#include<cstdio>using namespace std;int main(){ int n,m,t; while(cin>>m) { t=m; //给m另外赋值,为了区别因数是一个还是有多个 for(int i=2;i<=m;i++) //从2开始,一直到m数字本身 { if(t%i==0) //如果能被整除,就一直除,知道除尽这个数为止 { while(t%i==0) { if(t==m) //如果是第一个因子,那么整除前应该跟m相等 printf("%d",i); else printf("*%d",i); //如果不是,则按一般情况处理 t=t/i; //一直整除,知道不能整除为止 } } } cout<<endl; } return 0;}
hdu 1211
题目理解起来颇为费劲,不过看明白了就很简单了。
给你p、q、e要你求出d,然后根据后面给出的数字,作为小c代入M = D(c) = c(d) mod n,求出来的M的值用字符的形式输出即可。
#include<iostream>#include<cstdio>using namespace std;int main(){ long long p,q,e,l,a; while(cin>>p>>q>>e>>l) { while(l--) { cin>>a; long long n,fn,d,c,sum=1,i; n=p*q; fn=(p-1)*(q-1); for(i=1;;i++) if((i*e)%fn==1) { d=i; //暴力求d break; } for(int j=1;j<=d;j++) sum=sum*a%n; printf("%c",sum); //求出M并且以字符的形式输出 } cout<<endl; } return 0;}
hdu 1215
跟1164类似,也是求因子数,只不过是要求的是因子数之和,在这里要注意一个问题,因为数据比较大,循环开的大小只需要根号m即可,因为每个数的因子都是成对出现的,必然有一个因子大于或等于根号m,而另一个因子小于或等于根号m。
#include<iostream>using namespace std;int main(){ int n,m; cin>>n; while(n--) { int sum=1; cin>>m; for(int i=2;i*i<=m;i++) //避免超时,循环次数减少为根号 if(m%i==0) { if(i!=m/i) sum=sum+i+m/i; //得到一个因子,并且借此把另一个因子也求出来加上去 else sum=sum+i; } cout<<sum<<endl; } return 0;}
hdu 1222
点拨:本题的本质是求两个数是否有大于1的公因数
#include<iostream>using namespace std;int gcd(int x,int y){ int p; while(x%y) { p=x%y; x=y; y=p; } return y;}int main(){ int n; cin>>n; while(n--) { int a,b,t; cin>>a>>b; if(a<b) { t=a; a=b; b=t; } if(gcd(a,b)==1) cout<<"NO"<<endl; else cout<<"YES"<<endl; } return 0;}
hdu 1286
首先应该求出所有素因子,表示成唯一分解定理的形式,本题可以理解为求一个数n以内与n互素的数的个数。运用欧拉公式
N(n)=n*(1-1/p1)*(1-1/p2)···(其中p1、p2为能被n整除的素因子)
#include<iostream>using namespace std;int main(){ int n,m,t; cin>>n; while(n--) { cin>>m; int sum=m; for(int i=2;i<=m;i++) { if(m%i==0) { sum=sum/i*(i-1); while(m%i==0) m=m/i; } } if(m>1) sum=sum/m*(m-1); cout<<sum<<endl; } return 0;}
hdu 1299
通常给出的思路是:可以暴力求解,比如输入4, 就从5开始,一直寻找,直到所有结果都找到为止。于是就要考虑循环的跳出条件,因为开始你并不知道这个数的结果有多少种。运用数学知识,1 / x + 1 / y = 1 / n,假设x,y一大一小,即x>=y。则1/x<=1/y,所以有1/n<=1/y+1/y=2/y,变形得到较小的那个数y的范围是y<2n(注:x,y都必须大于n)。
因此用循环解答可以得到如下
for(int y=n+1;y<=2n;y++) //时间复杂度为n,即线性运算
…
范围条件都选好了,那么怎么判断该数是否满足条件呢?
将式子1 / x + 1 / y = 1 / n变形,得到1/x=1/n-1/y,再通分,将等式两边同时分子分母交换位置。
得到x=yk/(y-k) ,由x规定为整数可知,只要判断yk是否整除y-k即可得到结果是否满足条件。
另外,如果要考虑y是不是数据过大,可以进一步变形,令y=k+i,而x=k^2/i+k,
因此只要判断k的平方是否整除i即可。
得到的循环为for(int i=1;i<=k;i++)。
不过要注意,题目所给的n的范围最大是10的九次方,按照常理来说,应该是超时了,不信的话诸位可以试试,输出的结果不是WA,而是Time Limit Exceeded。因为题目所给的数据太大了。
在这里要另外转换思路求解了
既然线性运算超时,就必然要减少一些不必要数字的循环,因此思考方向就要转换到在n到2n之间,有那些数字是满足条件的,要想出一个筛选的条件。
继续看公式1 / x + 1 / y = 1 / n,前面一种思路已经打开了我们的思维,得到了公式x=k^2/i+k,用k的平方是否整除i来判断是否满足条件。我们知道,一个数k,如果整除i(i大于0,小于k),那么i一定就是k的因子了,不过在这里我们要的是k的平方的因子个数。
很容想到唯一分解定理:对于任一自然数n皆可唯一的表示为素数之积
N = p1^a1 * p2^a2 * p3^a3 * … * pn^an
#include<iostream>using namespace std;int main(){ long long s[100000],t; long long i,j,k=0; memset(s,0,sizeof(s)); for(i=2;i<100000;i++) //素数打表 { if(s[i]==0) { for(j=i*2;j<100000;j=j+i) s[j]=1; } } for(i=2;i<100000;i++) { if(s[i]==0) s[k++]=i; } s[k]='\0'; cin>>t; for(int count=1;count<=t;count++) { long long a,h,sum=1; cin>>a; for(i=0;s[i]!='\0';i++) //找出素因子 { h=0; while(a%s[i]==0) //整除至尽 { a=a/s[i]; h++; } sum=sum*(2*h+1); //根据公式求出个数 } if(a>1) sum=sum*3; //判断a为素数的情况 sum=sum/2+1; cout<<"Scenario #"<<count<<":"<<endl; cout<<sum<<endl<<endl; } return 0;}
- 8月1日解题报告
- 10月28日考试解题报告
- 10月30日解题报告
- 10月31日解题报告
- 11月03日解题报告
- 11月02日解题报告
- 11月04日解题报告
- 11月05日解题报告
- 11月06日解题报告
- 2017年2月18日晚解题报告
- 5月6日动态规划测试解题报告
- 【OTT】1月2日-1月8日OTT盒子观察报告
- 2013年3月17日 周赛 解题报告 -- from lanshui_Yang
- 2013年3月24日 周赛 解题报告 -- from lanshui_Yang
- 2017年2月26日第二次周考 解题报告
- 2017年3月5日 周考3 解题报告
- 【RqOct月赛】解题报告
- 四月月赛解题报告
- 单双向链表
- PHP中cURL的curl_getinfo函数返回的CURLINFO_HTTP_CODE是0
- 使用docker搭建弹性hadoop集群
- Android删除应用缓存的实现
- hdu 5335 Walk Out (搜索 + 路径输出)
- 8月1日解题报告
- ie6 javascript:void(0)、IE7 input透明、IE8 jquery动态加载css
- Ubuntu login incorrect问题解决
- 为什么我们需要TOGAF企业架构?——上海信息化培训中心
- git使用详细介绍
- Lucene
- jira找到字段的ID
- 修改linux打开文件最大数与最大线程数
- iOS之类别(category)在静态库中不能使用的问题