今天,陽光正好,適合敲程式碼,諸事皆宜。
先來兩道簡單的模擬題。
第一道
機器翻譯
輸出為5.
程式碼思路:很明顯需要用到佇列來存單詞,在建立一個bool陣列來儲存佇列中有沒有這個單詞,需不需要向外界查詢,如果需要並且佇列可以容下,則加入佇列並將bool陣列標記在佇列中有該單詞,如果佇列容不下,則將隊頭彈出,並用bool陣列標記彈出的數字在該佇列中沒有。
程式碼:
#include<bits/stdc++.h> using namespace std; queue<int> ss; bool mp[1010]; int n,m; int main() { int i,j,t,ans=0; cin>>m>>n; for(i=0;i<n;i++) { cin>>t; if(ss.size()>m) { int f=ss.front(); mp[f]=0; ss.pop(); } if(mp[t]==0) { ss.push(t); ans++; mp[t]=1; } } cout<<ans<<endl; return 0; }
第二道
神奇的幻方
輸出為:
8 1 6 3 5 7 4 9 2
思路:按題中步驟執行即可
首先找到1的位置,他在x=1,y=n/2+1;
然後判斷若x在第一行,但不在最後一列,就讓下一個數在x=n,y++的位置;
若不在第一行,在最後一列,就讓下一個數在x--,y=1的位置;
若在第一行最後一列,就讓下一個數在x++,y的位置;
若既不在最後一行也不在最後一列,並且右上方沒有數字,則下一個數在x--,y++的位置;
以上四個都不滿足就在x++,y的位置;
程式碼:
#include<bits/stdc++.h> using namespace std; int a[111][111]; int main() { int n,i,j,x,y; cin>>n; x=1;y=n/2+1; for(i=1;i<=n*n;i++) { a[x][y]=i; if(x==1&&y!=n) { x=n;y++; } else if(y==n&&x!=1) { y=1;x--; } else if(x==1&&y==n) { x++; } else if(a[x-1][y+1]==0) { x--;y++; } else x++; } for(i=1;i<=n;i++) { for(j=1;j<=n;j++) cout<<a[i][j]<<" "; cout<<endl; } return 0; }
一道二分的題
靈能探索
連結:https://ac.nowcoder.com/acm/contest/639/A
來源:牛客網
思路:二分邊界是從[靈能的最小值,靈能總和],check()函式的書寫:迴圈陣列,累加如果大於等於mid的值,則讓con++,s=0,繼續迴圈直到結束。判斷con的值是否大於等於題中輸入的組數,大於返回1,證明mid的值還可以在大,就讓l=mid+1,ans=mid,如果con的值不大於,證明mid的值大了,則需要r=mid-1,在進行判斷找出合適的mid的值。
程式碼:
#include<bits/stdc++.h> using namespace std; const long long N=100005; long long n,k,ans,a[N]; long long check(long long x) { long long i,j,s=0,con=0; for(i=0;i<n;i++) { s+=a[i]; if(s>=x) { con++; s=0; } } if(con>=k) return 1; return 0; } int main() { long long i,j,minx=100005,sum=0; long long l,r,mid; cin>>n>>k; for(i=0;i<n;i++) { cin>>a[i]; minx=min(minx,a[i]); sum+=a[i]; } l=minx;r=sum; while(l<=r) { mid=(l+r)/2; if(check(mid)) { l=mid+1; ans=mid; } else r=mid-1; } cout<<ans<<endl; }
一個乍一看是一道bfs搜尋題,然而他卻是到遞推題。
好心酸。。。。。
過河卒
連結:https://ac.nowcoder.com/acm/contest/639/B
來源:牛客網
先說說bfs的思路:從(1,1)開始搜尋,遇到馬或者超界就不放入佇列裡,最後如果佇列到達了終點則ans++;
程式碼:可惜只過了75%的資料
#include<bits/stdc++.h> using namespace std; const int mod=10000007; int n,m,x,y,ans; int xx[2]={1,0},yy[2]={0,1}; int v[1000][1000]; int vis[1000][1000]; struct node { int a,b; }; void bfs(int X,int Y) { vis[X][Y]=1; node t; t.a=X;t.b=Y; queue<node> p; p.push(t); while(!p.empty()) { node g=p.front(); p.pop(); if(g.a==n&&g.b==m) { ans++; continue; } for(int i=0;i<2;i++) { int w=g.a+xx[i]; int l=g.b+yy[i]; if(v[w][l]!=1&&vis[w][l]!=1&&w>=1&&w<=n&&l>=1&&l<=m) { p.push(node{w,l}); } } } return ; } int main() { int i,j; cin>>n>>m>>x>>y; v[x][y]=1; v[x-1][y-2]=1; v[x-2][y-1]=1; v[x-2][y+1]=1; v[x-1][y+2]=1; v[x+1][y-2]=1; v[x+2][y-1]=1; v[x+1][y+2]=1; v[x+2][y+1]=1; bfs(1,1); cout<<ans%mod<<endl; return 0; }
正解:遞推dp[i][j]=dp[i-1][j]+dp[i][j-1]
現將馬的所有可去的位置用v[][]的二維陣列標記上,然後將表格的第一行和第一列dp[][]賦值為1,如果途中遇到馬的位置,則停下結束迴圈,馬下面的將不會走故而可以結束迴圈,最終用二重迴圈從(2,2)開始計算如果不是馬的位置則dp[i][j]=(dp[i-1][j]+dp[i][j-1])%mod,否則dp[i][j]=0;
最終輸出dp[n][m]%mod的值,在這裡特別宣告一定要在計算dp[i][j]的時候也要取mod,因為數字很大容易超限,導致錯誤。
程式碼:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const ll mod=10000007; ll n,m,ans,x,y; int x1[9]={0,-2,-1,1,2,2,1,-1,-2}; int yy[9]={0,1,2,2,1,-1,-2,-2,-1}; ll dp[1004][1004]; ll v[1004][1004]; int main() { ll i,j; cin>>n>>m>>x>>y; v[x][y]=1; for(i=1;i<=8;i++) { if(x+x1[i]>=1&&y+yy[i]>=1) v[x+x1[i]][y+yy[i]]=1; } for(i=1;i<=n;i++) { if(v[i][1]==0) dp[i][1]=1; else break; } for(j=1;j<=m;j++) { if(v[1][j]==0) dp[1][j]=1; else break; } for(i=2;i<=n;i++) { for(j=2;j<=m;j++) { if(v[i][j]==0) dp[i][j]=(dp[i-1][j]+dp[i][j-1])%mod; else dp[i][j]=0; } } cout<<dp[n][m]%mod<<endl; return 0; }
ACM之旅仍在繼續,加油!!少年