AlenaNuna

导航

HJ41~HJ50 华为机试题库

HJ41 称砝码

题目:https://www.nowcoder.com/practice/f9a4c19050fc477e9e27eb75f3bfd49c?tpId=37&tqId=21264&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 int main(){
 4     ios_base::sync_with_stdio(false);
 5     cin.tie(NULL);
 6     int n,sum,cnt;
 7     while(cin>>n){
 8         vector<int>m(n);
 9         vector<int>x(n);
10         for(int i=0;i<n;i++)
11             cin>>m[i];
12         for(int i=0;i<n;i++)
13             cin>>x[i];
14         sum=0;
15         for(int i=0;i<n;i++)
16             sum+=m[i]*x[i];
17         vector<vector<bool>>dp(2,vector<bool>(sum+1,0));
18         dp[0][0]=dp[1][0]=1;cnt=1;
19         for(int i=0;i<n;i++){
20             for(int k=0;k<=sum;k++)
21                 dp[i&1][k]=dp[(i+1)&1][k];
22             for(int j=1;j<=x[i];j++){
23                 for(int k=m[i];k<=sum;k++){
24                     if(k-m[i]*j>=0&&dp[!(i&1)][k-m[i]*j]&&!dp[i&1][k]){
25                         dp[i&1][k]=1;
26                         cnt++;
27                     }
28                 }
29             }
30         }
31         cout<<cnt<<endl;
32     }
33 }

 方法二:一维dp:

 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 n,sum,cnt;
 7     while(cin>>n){
 8         vector<int>m(n);
 9         vector<int>x(n);
10         for(int i=0;i<n;i++)
11             cin>>m[i];
12         for(int i=0;i<n;i++)
13             cin>>x[i];
14         sum=0;
15         for(int i=0;i<n;i++)
16             sum+=m[i]*x[i];
17         vector<bool>dp(sum+1,0);
18         dp[0]=1;cnt=1;
19         for(int i=0;i<n;i++){
20             for(int j=sum;j>=0;j--)
21                 if(dp[j]){
22                     for(int k=1;k<=x[i];k++)
23                         if(j+m[i]*k<=sum&&dp[j+m[i]*k]==0){
24                             dp[j+m[i]*k]=1;
25                             cnt++;
26                         }
27                 }
28         }
29         cout<<cnt<<endl;
30     }
31 }

 方法三:注意到砝码称出来的重量不能重复,所以使用set。思路类似方法2,因为set默认是从小到大排序,所以需要使用一个仿函数来重载排序方法,变为从大到小排序。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 struct compareset{
 4     bool operator()(const int&a,const int&b){
 5         return a>b;
 6     }
 7 };
 8 int main(){
 9     ios_base::sync_with_stdio(false);
10     cin.tie(NULL);
11     int n;
12     while(cin>>n){
13         vector<int>m(n);
14         vector<int>x(n);
15         for(int i=0;i<n;i++)
16             cin>>m[i];
17         for(int i=0;i<n;i++)
18             cin>>x[i];
19         set<int,compareset>st;
20         st.insert(0);
21         for(int i=0;i<n;i++){
22             for(auto t:st){
23                 for(int j=1;j<=x[i];j++){
24                     st.insert(t+j*m[i]);
25                 }
26             }
27         }
28         cout<<st.size()<<endl;
29     }
30 }

 HJ42 学英语

题目:https://www.nowcoder.com/practice/1364723563ab43c99f3d38b5abef83bc?tpId=37&tqId=21265&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 string w[20],v[20],p[10];
 4 int n;
 5 void init(){
 6     w[1]="one";
 7     w[2]="two";
 8     w[3]="three";
 9     w[4]="four";
10     w[5]="five";
11     w[6]="six";
12     w[7]="seven";
13     w[8]="eight";
14     w[9]="nine";
15     w[10]="ten";
16     w[11]="eleven";
17     w[12]="twelve";
18     w[13]="thirteen";
19     w[14]="fourteen";
20     w[15]="fifteen";
21     w[16]="sixteen";
22     w[17]="seventeen";
23     w[18]="eighteen";
24     w[19]="nineteen";
25     v[2]="twenty";
26     v[3]="thirty";
27     v[4]="forty";
28     v[5]="fifty";
29     v[6]="sixty";
30     v[7]="seventy";
31     v[8]="eighty";
32     v[9]="ninety";
33     p[0]="and";
34     p[1]="hundred";
35     p[2]="thousand";
36     p[3]="million";
37     p[4]="billion";
38     return;
39 }
40 void Work(int x){
41     if(x/100){
42         cout<<w[x/100]<<" "<<p[1]<<" ";
43         x%=100;
44         if(x>0)cout<<p[0]<<" ";
45     }
46     if(x>0&&x<=19) {
47         cout<<w[x]<<" ";
48         return;
49     }
50     if(x==0)return;
51     cout<<v[x/10]<<" ";
52     x%=10;
53     if(x) cout<<w[x]<<" ";
54     return;
55 }
56 int main(){
57     init();
58     cin>>n;
59     if(n>=1000000){
60         Work(n/1000000);
61         n%=1000000;
62         cout<<p[3]<<" ";
63     }
64     if(n>=1000){
65         Work(n/1000);
66         n%=1000;
67         cout<<p[2]<<" ";
68     }
69     if(n>0){
70         Work(n);
71     }
72     return 0;
73 }

 HJ43 迷宫问题

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

一个经典又简单的搜索题,dfs和bfs都能写

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,m,mp[11][11],ansnum=1e9;
 4 bool book[11][11];
 5 int Dx[4]={-1,0,1,0};
 6 int Dy[4]={0,1,0,-1};
 7 struct WAY{
 8     int x,y;
 9 }ans[101],now[101];
10 void dfs(int x,int y,int cnt){
11     if(cnt>ansnum)return;
12     now[cnt].x=x;
13     now[cnt].y=y;
14     if(x==n-1&&y==m-1){
15         ansnum=cnt;
16         for(int i=1;i<=cnt;i++)
17             ans[i]=now[i];
18         return;
19     }
20     for(int i=0;i<4;i++){
21         int tx=x+Dx[i],ty=y+Dy[i];
22         if(tx>=0&&tx<n&&ty>=0&&ty<m){
23             if(mp[tx][ty]==0&&book[tx][ty]==0){
24                 book[tx][ty]=1;
25                 dfs(tx,ty,cnt+1);
26                 book[tx][ty]=0;
27             }
28         }
29     }
30 }
31 int main(){
32     cin>>n>>m;
33     for(int i=0;i<n;i++)
34         for(int j=0;j<m;j++)cin>>mp[i][j];
35     dfs(0,0,1);
36     for(int i=1;i<=ansnum;i++){
37         cout<<'('<<ans[i].x<<','<<ans[i].y<<')'<<'\n';
38     }
39 }

 HJ44 Sudoku

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

经典dfs题,难点在于想不起数独判定规则=。=

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int a[10][10],mp[10][10][10],cnt_mp[10][10],num_sta=0,ans[10][10];
 4 bool b[10],fg[10],fd=0;
 5 struct Sta{
 6     int x,y;
 7 }sta[100];
 8 struct ID{
 9     int x,y;
10 }id[10][10];
11 void Dfs(int k){
12     if(k>num_sta){
13         fd=1;
14         for(int i=1;i<=9;i++)
15             for(int j=1;j<=9;j++)
16                 ans[i][j]=a[i][j];
17         return;
18     }
19     if(fd)return;
20     int x=sta[k].x,y=sta[k].y;
21     for(int i=1;i<=cnt_mp[x][y];i++){
22         if(fd)return;
23         int wl=mp[x][y][i];
24         for(int j=1;j<=9;j++)fg[j]=1;
25         for(int j=1;j<=9;j++)if(j!=y)fg[a[x][j]]=0;
26         if(fg[wl]==0) continue;
27         for(int j=1;j<=9;j++)fg[j]=1;
28         for(int j=1;j<=9;j++)if(j!=x)fg[a[j][y]]=0;
29         if(fg[wl]==0) continue;
30         for(int j=1;j<=9;j++)fg[j]=1;
31         for(int dx=-1;dx<=1;dx++){
32             for(int dy=-1;dy<=1;dy++){
33                 fg[a[id[x][y].x+dx][id[x][y].y+dy]]=0;
34             }
35         }
36         if(fg[wl]==0) continue;
37         a[x][y]=wl;
38         Dfs(k+1);
39         a[x][y]=0;
40     }
41     return;
42 }
43 int main(){
44     for(int i=1;i<=9;i++){
45         for(int j=1;j<=9;j++){
46             scanf("%d",&a[i][j]);
47             id[i][j].x=(((i+2)/3)-1)*3+2;
48             id[i][j].y=(((j+2)/3)-1)*3+2;
49         }
50     }
51     for(int i=1;i<=9;i++){
52         for(int j=1;j<=9;j++)
53             if(a[i][j]==0){
54                 sta[++num_sta].x=i;
55                 sta[num_sta].y=j;
56                 for(int k=1;k<=9;k++)b[k]=1;
57                 for(int k=1;k<=9;k++){
58                     if(a[i][k]) b[a[i][k]]=0;
59                     if(a[k][j]) b[a[k][j]]=0;
60                 }
61                 for(int dx=-1;dx<=1;dx++){
62                     for(int dy=-1;dy<=1;dy++){
63                         b[a[id[i][j].x+dx][id[i][j].y+dy]]=0;
64                     }
65                 }
66                 for(int k=1;k<=9;k++)
67                     if(b[k]){
68                         cnt_mp[i][j]++;
69                         mp[i][j][cnt_mp[i][j]]=k;
70                     }
71             }
72     }
73     Dfs(1);
74     for(int i=1;i<=9;i++){
75         for(int j=1;j<=9;j++)printf("%d ",ans[i][j]);
76         puts("");
77     }
78     return 0;
79 }

 HJ45 名字的漂亮度

https://www.nowcoder.com/practice/02cb8d3597cf416d9f6ae1b9ddc4fde3?tpId=37&tqId=21268&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 int mp[300];
 4 bool cmp(const int&a,const int&b){
 5     return a>b;
 6 }
 7 int main(){
 8     ios_base::sync_with_stdio(false);
 9     cin.tie(NULL);
10     int n;
11     cin>>n;
12     while(n--){
13         string s; cin>>s;
14         memset(mp,0,sizeof(mp));
15         for(auto i:s)mp[(int)i]++;
16         sort(mp+1,mp+256,cmp);
17         int now=1,b=26,sum=0;
18         while(mp[now]>0){
19             sum+=mp[now]*b;
20             b--;
21             now++;
22         }
23         cout<<sum<<endl;
24     }
25 }

 HJ46 截取字符串

https://www.nowcoder.com/practice/a30bbc1a0aca4c27b86dd88868de4a4a?tpId=37&tqId=21269&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 int main(){
4     string s;int n;
5     cin>>s;
6     cin>>n;
7     for(int i=0;i<n;i++)cout<<s[i];
8 }
View Code

 HJ48 从单向链表中删除指定值的节点

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

链表模板题,正好练一下C++自带链表的用法/

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 struct ListNode{
 4     int val;
 5     ListNode* next;
 6     ListNode(int x):val(x),next(nullptr){}
 7 };
 8 void PrintList(ListNode* hd){
 9     while(hd!=nullptr){
10         cout<<hd->val<<" ";
11         hd=hd->next;
12     }
13     return;
14 }
15 ListNode* Delete(int val,ListNode* hd){
16     ListNode* dummy=new ListNode(0);
17     dummy->next=hd;
18     ListNode* pre=dummy;
19     ListNode* cur=hd;
20     while(cur!=nullptr){
21         if(cur->val==val){
22             pre->next=cur->next;
23             delete cur;
24             break;
25         }
26         pre=cur;
27         cur=cur->next;
28     }
29     ListNode* newhead=dummy->next;
30     delete dummy;
31     return newhead;
32 }
33 int main(){
34     ios_base::sync_with_stdio(false);
35     cin.tie(NULL);
36     int n,a,b;
37     cin>>n>>a;
38     ListNode* hd=new ListNode(a);
39     unordered_map<int,ListNode*>hash;
40     hash[a]=hd;
41     for(int i=1;i<n;i++){
42         cin>>a>>b;
43         ListNode* ia;
44         ListNode* ib;
45         if(hash[a]==nullptr)ia=new ListNode(a);
46         else ia=hash[a];
47         if(hash[b]==nullptr)ib=new ListNode(b);
48         else ib=hash[b];
49         if(ib->next==nullptr)
50             ib->next=ia;
51         else{
52             ia->next=ib->next;
53             ib->next=ia;
54         }
55         if(ia==hd) hd=ib;
56         hash[a]=ia;
57         hash[b]=ib;
58     }
59     int deleteval;
60     cin>>deleteval;
61     PrintList(Delete(deleteval,hd));
62     return 0;
63 }

 HJ50 四则运算

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

呜呜呜我真是个可怜的菜菜,这么多年了我终于写出了漂亮的四则运算代码

思路:

定义运算符优先级
- 使用yxj函数计算各个运算符的优先级,其中乘除为2,加减为1,左括号为0(无论如何都不优先计算左括号,直到遇到右括号)

运算函数Calc:
- 根据运算符 `op` 对栈顶的两个操作数 `a` 和 `b` 进行计算,并将计算结果压回栈中。

- 从操作数栈 `values` 中弹出两个操作数。
- 从操作符栈 `ops` 中弹出运算符。
- 计算结果并将其压入操作数栈。

计算表达式的值Work()
- 使用两个栈,一个存储操作数,一个存储操作符。
- 遍历表达式的每个字符,特判负号是不是负数的负号,处理数字、运算符和括号。
- 根据运算符的优先级进行计算。
- 最终返回操作数栈中的结果。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 bool isdigital(char c){
 4     if(c>='0'&&c<='9')return 1;
 5     return 0;
 6 }
 7 int yxj(char c){
 8     if(c=='+'||c=='-')return 1;
 9     if(c=='*'||c=='/')return 2;
10     return 0;
11 }
12 void Calc(stack<int>&vals,stack<char>&ops){
13     int b=vals.top();vals.pop();
14     int a=vals.top();vals.pop();
15     char op=ops.top();ops.pop();
16     int x;
17     if(op=='+')x=a+b;
18     else if(op=='-')x=a-b;
19     else if(op=='*')x=a*b;
20     else x=a/b;
21     vals.push(x);
22 }
23 void Work(const string&s){
24     stack<int>vals;
25     stack<char>ops;
26     for(int i=0;i<(int)s.size();i++){
27         int x=0,f=1;
28         if(s[i]=='-'){
29             if(i==0)f=-1;
30             if(i-1>=0&&(s[i-1]=='['||s[i-1]=='{'||s[i-1]=='('))f=-1;
31             if(f==-1) i++;
32         }
33         if(isdigital(s[i])){
34             while(i<(int)s.size()&&isdigital(s[i])){
35                 x=x*10+s[i]-'0';
36                 i++;
37             }
38             vals.push(f*x);
39         }
40         if(i==(int)s.size())break;
41         if(s[i]=='{'||s[i]=='['||s[i]=='(')
42             ops.push(s[i]);
43         else if(s[i]=='+'||s[i]=='-'||s[i]=='*'||s[i]=='/'){
44             while(!ops.empty()&&yxj(ops.top())>=yxj(s[i]))Calc(vals,ops);
45             ops.push(s[i]);
46         }
47         else{
48             char c;
49             if(s[i]=='}')c='{';else if(s[i]==']')c='[';else c='(';
50             while(ops.top()!=c)Calc(vals,ops);
51             ops.pop();
52         }
53     }
54     while(!ops.empty())Calc(vals,ops);
55     cout<<vals.top();
56 }
57 int main(){
58     string s;
59     cin>>s;
60     Work(s);
61 }

by:AlenaNuna

posted on 2024-09-16 14:51  AlenaNuna  阅读(7)  评论(0编辑  收藏  举报