HJ61 放苹果
题目:https://www.nowcoder.com/practice/bfd8234bb5e84be0b493656e390bdebf?tpId=37&tqId=21284&rp=1&ru=/exam/oj/ta&qru=/exam/oj/ta&sourceUrl=%2Fexam%2Foj%2Fta%3FtpId%3D37&difficulty=undefined&judgeStatus=undefined&tags=&title=
dfs(i,x,lst)表示正在放第i个盘子的苹果,总共还剩x个苹果,lst表示上个盘子放置的苹果数(从小到大,保证1 1 5和5 1 1不会被计数两次)
1 #include<bits/stdc++.h>
2 using namespace std;
3 int m,n,cnt=0;
4 void dfs(int i,int x,int lst){
5 if(i>n){
6 if(x==0) cnt++;
7 return;
8 }
9 for(int j=lst;j<=x;j++)
10 dfs(i+1,x-j,j);
11 }
12 int main(){
13 cin>>m>>n;
14 dfs(1,m,0);
15 cout<<cnt;
16 }
HJ62 查找输入整数二进制中1的个数
1 #include<bits/stdc++.h>
2 using namespace std;
3 int Work(int x){
4 int cnt=0;
5 for(int i=0;i<31;i++){
6 if(x&(1<<i))cnt++;
7 }
8 return cnt;
9 }
10 int main(){
11 int n;
12 while(cin>>n){
13 cout<<Work(n)<<endl;
14 }
15 }
HJ63 DNA序列
https://www.nowcoder.com/practice/e8480ed7501640709354db1cc4ffd42a?tpId=37&tqId=21286&rp=1&ru=/exam/oj/ta&qru=/exam/oj/ta&sourceUrl=%2Fexam%2Foj%2Fta%3FtpId%3D37&difficulty=undefined&judgeStatus=undefined&tags=&title=
太显然的滑窗,用个queue就可以很方便写
1 #include<bits/stdc++.h>
2 using namespace std;
3 void Work(const string&s,const int&k){
4 int len=s.size();
5 queue<char>que;
6 queue<char>mxgcque;
7 int gc=0,mxgc=0;
8 for(int i=0;i<k;i++){
9 que.push(s[i]);
10 if(s[i]=='G'||s[i]=='C') gc++;
11 }
12 mxgcque=que; mxgc=gc;
13 for(int i=k;i<len;i++){
14 if(que.front()=='G'||que.front()=='C')gc--;
15 que.pop();
16 que.push(s[i]);
17 if(s[i]=='G'||s[i]=='C') gc++;
18 if(gc>mxgc){
19 mxgc=gc;
20 mxgcque=que;
21 }
22 }
23 while(!mxgcque.empty()){
24 cout<<mxgcque.front();
25 mxgcque.pop();
26 }
27 }
28 int main(){
29 string s;
30 int n;
31 cin>>s>>n;
32 Work(s,n);
33 }
HJ65 查找两个字符串a,b中的最长公共子串
题目:https://www.nowcoder.com/practice/181a1a71c7574266ad07f9739f791506?tpId=37&tqId=21288&rp=1&ru=/exam/oj/ta&qru=/exam/oj/ta&sourceUrl=%2Fexam%2Foj%2Fta%3Fpage%3D2%26tpId%3D37%26type%3D37&difficulty=undefined&judgeStatus=undefined&tags=&title=
我处理边界情况一直都挺不可以的T_T这回也是漏了i==0,j==0时dp[i][j]=1;的情况啊啊
1 #include<bits/stdc++.h>
2 using namespace std;
3 int main(){
4 string a,b,c;
5 getline(cin,a);
6 getline(cin,b);
7 int la=a.size(),lb=b.size();
8 vector<vector<int>>dp(la+1,vector<int>(lb+1));
9 int ans=0;int fr;
10 for(int i=0;i<la;i++)
11 for(int j=0;j<lb;j++){
12 if(a[i]==b[j]){
13 if(i-1>=0&&j-1>=0)
14 dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);
15 else dp[i][j]=1;
16 }
17 else dp[i][j]=0;
18 if(dp[i][j]>ans){
19 ans=dp[i][j];
20 fr=i;
21 }
22 }
23 if(la<lb){
24 for(int i=0;i<la;i++)
25 for(int j=0;j<lb;j++){
26 if(dp[i][j]==ans){
27 fr=i;
28 for(int i=fr-ans+1;i<=fr;i++)cout<<a[i];
29 return 0;
30 }
31 }
32 }
33 else{
34 for(int j=0;j<lb;j++)
35 for(int i=0;i<la;i++){
36 if(dp[i][j]==ans){
37 fr=j;
38 for(int i=fr-ans+1;i<=fr;i++)cout<<b[i];
39 return 0;
40 }
41 }
42 }
43 }
HJ67 24点游戏算法
题目:https://www.nowcoder.com/practice/fbc417f314f745b1978fc751a54ac8cb?tpId=37&tqId=21290&rp=1&ru=/exam/oj/ta&qru=/exam/oj/ta&sourceUrl=%2Fexam%2Foj%2Fta%3FtpId%3D37&difficulty=undefined&judgeStatus=undefined&tags=&title=
非常非常有意思,思路很巧妙的一道题。
dfs(const vector<double>&a)处理当前数字组。
如果a.size()==1,则证明数字组中只剩一个数字。判断该数字是否为24。由于是浮点数,需要考虑精度问题。fabs用于计算double范围的绝对值。(fabsl用于计算long double范围的绝对值)fabs(a[0]-24)<1e-6就是在抹去精度的影响。
如果a数组中的数不止1的话,则i和j分别遍历a中的两个位置不同的数字,然后依次进行加减乘除处理,将处理后的结果扔进新的数字组b中,b中还需要添加本轮运算中没有用到的数字(非a[i]非a[j]),然后拿b数字组扔进dfs里进行新一轮的计算。pop_back()可以用于取出vector<>的最后一个元素。所以可以用来方便地回溯。每次取出两个数字进行运算的过程即是在模仿括号运算的过程。
注意使用除法时被除数不能为0。
1 #include<bits/stdc++.h>
2 using namespace std;
3
4 void dfs(const vector<double>&a){
5 if(a.size()==1){
6 if(fabs(a[0]-24)<1e-6){
7 puts("true");
8 exit(0);
9 }
10 return;
11 }
12 for(int i=0;i<a.size();i++){
13 for(int j=0;j<a.size();j++){
14 if(i!=j){
15 vector<double>b;
16 b.clear();
17 for(int k=0;k<a.size();k++)
18 if(k!=i&&k!=j)b.push_back(a[k]);
19 double x=a[i],y=a[j];
20 b.push_back(x+y); dfs(b);
21 b.pop_back(); b.push_back(x-y); dfs(b);
22 b.pop_back(); b.push_back(x*y); dfs(b);
23 b.pop_back(); if(y!=0){b.push_back(x/y); dfs(b);}
24 }
25 }
26 }
27 }
28 int main(){
29 vector<double>a(4);
30 for(int i=0;i<4;i++) cin>>a[i];
31 dfs(a);
32 puts("false");
33 }
HJ68 成绩排序
https://www.nowcoder.com/practice/8e400fd9905747e4acc2aeed7240978b?tpId=37&tqId=21291&rp=1&ru=/exam/oj/ta&qru=/exam/oj/ta&sourceUrl=%2Fexam%2Foj%2Fta%3FtpId%3D37&difficulty=undefined&judgeStatus=undefined&tags=&title=
1 #include<bits/stdc++.h>
2 using namespace std;
3 struct Stu{
4 string name;
5 int a;
6 }st[210];
7 int n,t;
8 bool cmp1(const Stu&a,const Stu&b){
9 return a.a>b.a;
10 }
11 bool cmp2(const Stu&a,const Stu&b){
12 return a.a<b.a;
13 }
14 int main(){
15 cin>>n;
16 cin>>t;
17 for(int i=1;i<=n;i++){
18 cin>>st[i].name>>st[i].a;
19 }
20 if(t==0)stable_sort(st+1,st+n+1,cmp1);
21 else stable_sort(st+1,st+n+1,cmp2);
22 for(int i=1;i<=n;i++){
23 cout<<st[i].name<<" "<<st[i].a<<endl;
24 }
25 return 0;
26 }
HJ69 矩阵乘法
题目:https://www.nowcoder.com/practice/ebe941260f8c4210aa8c17e99cbc663b?tpId=37&tqId=21292&rp=1&ru=/exam/oj/ta&qru=/exam/oj/ta&sourceUrl=%2Fexam%2Foj%2Fta%3FtpId%3D37&difficulty=undefined&judgeStatus=undefined&tags=&title=
范围很温和,传统的模拟就能解决
我竟然把vector二维数组写成了vector<int,vector<int>>………………真是犯莫名其妙的错误
传统算法效率是O(n^3),大约能计算n=500的范围。如果想更快可以使用Strassen算法,效率是O(n^2.81)的,大约能计算n=1000的情况(但是由于递归的复杂度较高,小范围数据可能跑的比传统算法慢)。Strassen算法的原理:递归地将矩阵分解成更小的子矩阵,减少了乘法运算次数。步骤:1.将矩阵分解成4个子矩阵;2.计算7个中间矩阵;3.利用中间矩阵组合得到最终结果矩阵
下面是传统算法的代码。
1 #include<bits/stdc++.h>
2 using namespace std;
3 int main(){
4 ios_base::sync_with_stdio(false);
5 cin.tie(NULL);
6 int x,y,z;
7 while(cin>>x>>y>>z){
8 vector<vector<int>>A(x+1,vector<int>(y+1));
9 vector<vector<int>>B(y+1,vector<int>(z+1));
10 vector<vector<int>>C(x+1,vector<int>(z+1));
11 for(int i=1;i<=x;i++)
12 for(int j=1;j<=y;j++)cin>>A[i][j];
13 for(int i=1;i<=y;i++)
14 for(int j=1;j<=z;j++)cin>>B[i][j];
15 for(int i=1;i<=x;i++){
16 for(int j=1;j<=z;j++){
17 for(int k=1;k<=y;k++)C[i][j]+=A[i][k]*B[k][j];
18 }
19 }
20 for(int i=1;i<=x;i++){
21 for(int j=1;j<=z;j++)cout<<C[i][j]<<" ";
22 cout<<endl;
23 }
24 }
25 }
HJ70 矩阵乘法计算量估算
题目:https://www.nowcoder.com/practice/15e41630514445719a942e004edc0a5b?tpId=37&tqId=21293&rp=1&ru=/exam/oj/ta&qru=/exam/oj/ta&sourceUrl=%2Fexam%2Foj%2Fta%3FtpId%3D37&difficulty=undefined&judgeStatus=undefined&tags=&title=
不是。。。哥们。。原来矩阵乘法必定是1对1啊,原来矩阵乘法时左矩阵的列必定等于右矩阵的行啊T_T不是,哥们…第一次感觉线性代数这么有用
一切恐惧的来源都是基础数学知识的不足T_T我写了个好复杂的误解版,虽然还是把题目过了,但是后知后觉发现不会我理解错概念了吧!?然后马上改了个简单版,结果就是秒过。才发现自己蠢的可以,连线性代数的基本概念都忘了。啊啊啊啊…Orz
1 #include<bits/stdc++.h>
2 #define ll long long
3 using namespace std;
4 ll Work(stack<pair<int,int>>&st){
5 int v=st.top().second;
6 st.pop();
7 ll sum=0;
8 int x=st.top().first,y=st.top().second;
9 st.pop();
10 sum+=x*y*v;
11 x=x;y=v;
12 st.push(make_pair(x,y));
13 return sum;
14 }
15 int main(){
16 int n; ll sum=0;
17 cin>>n;
18 vector<pair<int,int>>a(n);
19 for(int i=0;i<n;i++)
20 cin>>a[i].first>>a[i].second;
21 string s;cin>>s;
22 stack<pair<int,int>>st;
23 for(unsigned int i=0;i<s.size();i++){
24 if(s[i]=='(');
25 else if(s[i]!=')')
26 st.push(a[s[i]-'A']);
27 else sum+=Work(st);
28 }
29 cout<<sum;
30 }
by:AlenaNuna