2022-09-30-寒武纪软件笔试第二场-63分钟-70分
中间面了个hr面,12分钟。
第二题扣10分(40%),第三题扣20分(80%),第四题一看以为完了不能及格了,dfs都打出来了,发现是任选一个,不是从两端选,连暴力都做不出来,后突然就想到从相对性角度考虑了,一遍过。。。生存与毁灭,就在一念之间。
后三题每个用例都是由多个用例构成的,难以偷分。。
每题题意都已大致写明在下面。
// 第一题 // 7.5min 100% 25' // 识别出山峰点的个数,即比周围8个位置都大的点的个数 // 1<=n<=100 #include<iostream> #include<vector> using namespace std; int main(){ int n;cin>>n; vector<string> a(n); for(int i=0;i<n;i++) cin>>a[i]; int d[8][2]={{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}}; int ans=0; for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ bool h=1; for(int k=0;k<8;k++){ int x=i+d[k][0],y=j+d[k][1]; if(0<=x&&x<n&&0<=y&&y<n){ if(a[i][j]<=a[x][y]){ h=0;break; } } } if(h)ans++; } } cout<<ans; return 0; } // 第二题 // 26min 60% 25' -10' // 题目:d[0]=1, d数组的奇数位的值是前一位的值的两倍,偶数位的值比前一位的值多1 // 求d的第n位(60>=n>=0,1<=t<=10) // 开始以为是数字太大了存不下,后改成python还是60%,改成字符串相加还是60% // 后打印出来发现最大也就32位就可以存下,因为有一半是在做加法,最多翻倍了30次 #include<iostream> #include<algorithm> #include<vector> using namespace std; string add(string s1,string s2){ string ans; int c=0; for(int i=s1.length()-1,j=s2.length()-1;i>=0||j>=0;){ if(i>=0&&j>=0){ int a=s1[i]-'0' + s2[j]-'0'+c; ans.append(string(1,'0'+(a%10))); c=a/10; i--,j--; }else if(i>=0){ int a=s1[i]-'0'+c; ans.append(string(1,'0'+(a%10))); c=a/10; i--; }else{ int a=s2[j]-'0'+c; ans.append(string(1,'0'+(a%10))); c=a/10; j--; } } if(c>0) ans.append(string(1,'0'+c)); reverse(ans.begin(),ans.end()); return ans; } int main(){ int t;cin>>t; // 60% // vector<unsigned long long> h; // h.push_back(1); // while(t--){ // int n;cin>>n; // // cout<<h.size()<<", n="<<n<<"\n"; // if(n<h.size()) cout<<h[n]<<"\n"; // else{ // while(n>=h.size()){ // // cout<<"back= "<<h.back()<<"\n"; // h.push_back((h.size()%2==1)?h.back()*2LL:h.back()+1); // // cout<<"pushback= "<<h.back()<<"\n"; // } // cout<<h[n]<<"\n"; // } // } vector<string> h(61); h[0]="1"; for(int i=1;i<=60;i++){ if(i%2==1){ h[i]=add(h[i-1],h[i-1]); }else{ h[i]=add(h[i-1],"1"); } // cout<<h[i]<<"\n"; } while(t--){ int n;cin>>n; if(t>0) cout<<h[n]<<"\n"; else cout<<h[n]; } return 0; } // 第二题 python 60% t=int(input()) for i in range(t): n=int(input()) a=1 for j in range(1,n+1): if j&1 == 1: a=a*2 else: a=a+1 print(a) // 第三题 22min 20% 25' -20' // 给出数组B,求数组A,A和B的长度一样,1<=A[i]<=B[i] // 使得 sum_{i=2}^N |A[i]-A[i-1]| 最大 // 1<=t<=20, 1<=n<=100000 // 1<=B[i]<=100 #include<iostream> #include<algorithm> #include<vector> using namespace std; int main(){ int t;cin>>t; while(t--){ int n;cin>>n; vector<int> b(n),a(n,0); for(int i=0;i<n;i++)cin>>b[i]; int s=0,l1=0,l2=0; for(int i=0;i<n;i++){ int j=i+1; while(j<n&&b[j]>=b[j-1]) j++; int s1=0,s2=0; for(int k=i;k<j;k+=2) s1+=b[k]-1; for(int k=i+1;k<j;k+=2) s2+=b[k]-1; if(s1+l1<s2+l2) s+=s2+l2; else{ s+=s1+l1; } // s+=max(s1,s2); if(j<n){ l1=b[j-1]-b[j]; l2=b[j-1]-1; // s+=b[j-1]-1; }else l1=l2=0; i=j; } s+=max(l1,l2); cout<<s<<"\n"; } return 0; } // 第四题 7min 20% 25' !!! // 整除游戏,给出一个数组a,A和B两人轮流操作,A先手 // 每次操作是从数组里取一个数字 // 最后A取的数字的和为Sa, B取的数字的和为Sb // 如果|Sa-Sb|能被3整除,则B赢,否则A赢 // 1<=t<=100 // 1<=ai<=2000 // 1<=n<=2000 #include<iostream> #include<vector> using namespace std; int main(){ int t;cin>>t; while(t--){ int n;cin>>n; vector<int> a(n,0); int e[3]={0}; for(int i=0;i<n;i++){ cin>>a[i]; a[i]=a[i]%3; e[a[i]]++; } // for(int i=0;i<3;i++) // e[i]=e[i]%2; if(e[1]%2!=0||e[2]%2!=0) cout<<"Alice\n"; else cout<<"Bob\n"; } return 0; }#寒武纪##寒武纪校招##23届秋招笔面经##23秋招#