AlenaNuna

导航

简单题集锦

HJ108 求最小公倍数

题目:https://www.nowcoder.com/practice/22948c2cad484e0291350abad86136c3?tpId=37&tqId=21331&rp=1&ru=/exam/oj/ta&qru=/exam/oj/ta&sourceUrl=%2Fexam%2Foj%2Fta%3FtpId%3D37&difficulty=undefined&judgeStatus=undefined&tags=&title=

复习一下辗转相除法:

原理证明

设两数为a、b(a>b),用gcd(a,b)表示a,b的最大公约数,r=a (mod b) 为a除以b的余数,k为a除以b的商,即a÷b=kr。辗转相除法即是要证明gcd(a,b)=gcd(b,r)。

第一步:令c=gcd(a,b),则设a=mc,b=nc

第二步:根据前提可知r =a-kb=mc-knc=(m-kn)c

第三步:根据第二步结果可知c也是r的因

第四步:可以断定m-kn与n互质(假设m-kn=xd,n=yd (d>1),则m=kn+xd=kyd+xd=(ky+x)d,则a=mc=(ky+x)cd,b=nc=ycd,则a与b的一个公约数cd>c,故c非a与b的最大公约数,与前面结论矛盾),因此c也是b与r的最大公约数。

从而可知gcd(b,r)=c,继而gcd(a,b)=gcd(b,r)。

证毕。

以上步骤的操作是建立在刚开始时r≠0的基础之上的。即m与n亦互质。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int a,b;
 4 int gcd(int a,int b){
 5     if(b) return gcd(b,a%b);
 6     else return a;
 7 }
 8 int main(){
 9     cin>>a>>b;
10     cout<<a*b/gcd(a,b);
11     return 0;
12 }

 

HJ107 求解立方根

题目:https://www.nowcoder.com/practice/caf35ae421194a1090c22fe223357dca?tpId=37&tqId=21330&rp=1&ru=/exam/oj/ta&qru=/exam/oj/ta&sourceUrl=%2Fexam%2Foj%2Fta%3FtpId%3D37&difficulty=undefined&judgeStatus=undefined&tags=&title=

不让用库函数,那就显然是二分。几乎没怎么写过小数二分,差点给我写老实了=。=幸好还是简单

因为三次方只在[0,+∞]上满足单调性,就分成正负两种情况处理。

然后要注意 l 和 r 的范围,一个数的三次方不一定比它本身大。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 double n,l,r,mid;
 4 int main(){
 5     cin>>n;
 6     bool f=0;
 7     if(n<0){
 8         n=-n;
 9         f=1;
10     }
11     l=0;r=100;
12     while(l<=r){
13         mid=(l+r)/2;
14         if(mid*mid*mid<=n){
15             l=mid+0.01;
16         }
17         else{
18             r=mid-0.01;
19         }
20     }
21     if(f) mid=-mid;
22     printf("%.1lf",mid);
23     return 0;
24 }

 

HJ106 字符逆序

题目:https://www.nowcoder.com/practice/cc57022cb4194697ac30bcb566aeb47b?tpId=37&tqId=21329&rp=1&ru=/exam/oj/ta&qru=/exam/oj/ta&sourceUrl=%2Fexam%2Foj%2Fta%3Fpage%3D3%26tpId%3D37%26type%3D37&difficulty=undefined&judgeStatus=undefined&tags=&title=

就当作练一下输入。

简简单单的,很安心=v=

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int len=0,st[10010];
 4 void init(){
 5     char c=getchar();
 6     while(c!='\n'){
 7         st[len++]=c;
 8         c=getchar();
 9     }
10     return;
11 }
12 int main(){
13     init();
14     for(int i=len-1;i>=0;i--)
15         printf("%c",st[i]);
16     return 0;
17 }

 

HJ103 Redraiment的走法

题目:https://www.nowcoder.com/practice/24e6243b9f0446b081b1d6d32f2aa3aa?tpId=37&tqId=21326&rp=1&ru=/exam/oj/ta&qru=/exam/oj/ta&sourceUrl=%2Fexam%2Foj%2Fta%3Fpage%3D3%26tpId%3D37%26type%3D37&difficulty=undefined&judgeStatus=undefined&tags=&title=

一个简单得很安心的最长上升子序列,n甚至只有200

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,a[220],dp[220],ans;
 4 int main(){
 5     cin>>n;
 6     for(int i=1;i<=n;i++)
 7         cin>>a[i];
 8     for(int i=1;i<=n;i++) dp[i]=1;
 9     for(int i=2;i<=n;i++){
10         for(int j=1;j<i;j++)
11             if(a[j]<a[i])dp[i]=max(dp[i],dp[j]+1);
12     }
13     ans=1;
14     for(int i=1;i<=n;i++)
15         ans=max(ans,dp[i]);
16     cout<<ans;
17     return 0;
18 }

 然后我就思考了一下nlogn的做法

就是维护一个b[k]数组记录截至当前位置为止,满足长度为k的上升子序列的最小的a[i]值。

然后二分进行判断,顺便一直维护b[k]数组保持值最小就好啦。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e5+10;
 4 int n,a[maxn],b[maxn],c[maxn],ans=1;
 5 int Ef(int x){
 6     int l,r,mid;
 7     l=1;r=ans;
 8     while(l<=r){
 9         mid=(l+r)/2;
10         if(x>b[mid])l=mid+1;
11         else r=mid-1;
12     }
13     return l;
14 }
15 int main(){
16     cin>>n;
17     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
18     for(int i=1;i<=n;i++) c[i]=1;
19     b[1]=a[1];
20     for(int i=2;i<=n;i++){
21         b[1]=min(b[1],a[i]);
22         int t=Ef(a[i]);
23         if(t>ans) b[++ans]=a[i];
24         b[t]=min(b[t],a[i]);
25     }
26     cout<<ans;
27     return 0;
28 }

感觉自己语言能力好捉急呀。。。。思路讲的不太好,但是难以把抽象的东西表达清楚…无奈

今晚随便写了QQ音乐的笔试,又被核心代码模式恶心得不清,还迟到了二十多分钟入场= 。=

不管了,继续刷题,华为我来噜> <!

posted on 2024-09-05 15:31  AlenaNuna  阅读(7)  评论(0编辑  收藏  举报